ORM

Django ORMでデータを辞書形式で取得|values()の使い方

DjangoのORMで取得したデータを辞書形式やタプル形式で受け取りたい場合は、values()values_list()メソッドを使用します。特定のフィールドだけを取得したり、テンプレートやAPI向けにデータを整形する際に便利です。

基本的な使い方

views.py
model = Company.objects.all().values();

説明

Step 1valuesメソッドの基本

Djangoでは、以下の形式でモデルのデータを辞書型にして取得することができます:

モデル.objects.all().values()
モデル.objects.filter(条件).values()

データはリストの中に{フィールド名: 値}の形式で取得されます。

例:

companies = Company.objects.all().values()
# 結果: <QuerySet [{'id': 1, 'name': 'test'}, {'id': 2, 'name': 'example'}]>

Step 2特定のフィールドのみ取得

values()メソッドに引数を指定することで、特定のフィールドのみを取得できます:

companies = Company.objects.all().values('name')
# 結果: <QuerySet [{'name': 'test'}, {'name': 'example'}]>

複数のフィールドを指定する場合:

companies = Company.objects.all().values('id', 'name')
# 結果: <QuerySet [{'id': 1, 'name': 'test'}, {'id': 2, 'name': 'example'}]>

Step 3QuerySetからリストへの変換

データは<QuerySet [{'id': 1, 'name': 'test'}]>のような形式でQuerySetというものがついています。フロントエンドにこのデータを返したいときは、以下の形式で通常のリストに変換します:

list(データを格納した変数)

例:

companies = Company.objects.all().values()
companies_list = list(companies)
# 結果: [{'id': 1, 'name': 'test'}, {'id': 2, 'name': 'example'}]

Step 4単一レコードの辞書型取得

単一のモデルを辞書型データとして取得したいときは、以下の形式で記入します:

モデル.objects.values().get(条件)

values()が末尾ではなくなるため注意してください。

例:

company = Company.objects.values().get(id=1)
# 結果: {'id': 1, 'name': 'test'}

特定のフィールドのみを取得する場合:

company = Company.objects.values('name').get(id=1)
# 結果: {'name': 'test'}

Step 5辞書型データへのアクセス

取得した辞書型データには、Pythonの辞書操作でアクセスできます:

# 単一レコードの場合
company = Company.objects.values().get(id=1)
company_name = company['name']
print(company_name)  # 'test'

# 複数レコードの場合
companies = Company.objects.all().values()
for company in companies:
    print(company['name'])

Step 6実践的な使用例

JSONレスポンスを返すビューでの使用例:

from django.http import JsonResponse
from .models import Company

def company_list_json(request):
    # 会社データを辞書型で取得
    companies = Company.objects.all().values()
    
    # リストに変換してJSONレスポンスとして返す
    return JsonResponse({
        'companies': list(companies)
    })

テンプレートでの使用例:

from django.shortcuts import render
from .models import Company

def company_list(request):
    # 会社データを辞書型で取得
    companies = Company.objects.all().values('id', 'name')
    
    # テンプレートに渡す
    return render(request, 'companies/company_list.html', {
        'companies': companies
    })

テンプレート内での使用(company_list.html):

<h1>会社一覧</h1>

<ul>
    {% for company in companies %}
        <li>ID: {{ company.id }} - 名前: {{ company.name }}</li>
    {% empty %}
        <li>登録されている会社はありません。</li>
    {% endfor %}
</ul>
ポイント

メリット: valuesメソッドを使用すると、必要なフィールドだけを取得できるため、メモリ使用量を削減できます。また、JSONに変換する際にも便利です。ただし、モデルインスタンスのメソッドにはアクセスできなくなるため、用途に応じて選択してください。

まとめ

  • values()でデータを辞書形式(dictのQuerySet)で取得できる
  • values_list()でデータをタプル形式で取得できる
  • 引数にフィールド名を指定すると、そのフィールドのみ取得される
  • values_list(flat=True)で単一フィールドをリスト形式で取得できる
  • 不要なフィールドの読み込みを避けることで、パフォーマンスが向上する
  • distinct()と組み合わせて重複を除外できる