Djangoで評価リストを使用してより良い質問を書く


Django ORMは素晴らしいです、しかし、それが非能率的な質問につながることができたので、それは常にその最も原始的な状態でそれを使用するのに良い考えであるかもしれません.
例えば、id、name、createdRADIAT、および削除されたかどうかを示すISHERDER削除フラグからなるレコードと呼ばれるデータベースモデルを考えます.
from django.db import models

class Record(models.Model):
  # id will be created automatically
  name = models.CharField(max_length=255)
  created_at = models.DateTimeField(auto_now_add=True)
  is_deleted = models.BooleanField(default=False)
レコードを使用してクエリを実行します.オブジェクト.filter ( isChanged = false );このデータベースのクエリは以下のようになります.
SELECT id,
       name,
       created_at,
       is_deleted
FROM   records
WHERE  NOT is_deleted; 
これはテーブルのすべてのフィールドを問い合わせるだけでなく、以下のようなモデルインスタンスのQuerySetを返します.
>>> Record.objects.filter(is_deleted=False)
<QuerySet [<Record: Record object (1)>, <Record: Record object (2)>, <Record: Record object (3)>]>
ほとんどの場合、モデルのすべてのフィールドを必要としません.さらに悪いことは、あなたの記録モデルが10のフィールドから成るならば、この質問はあなたの質問をかなり遅くしているデータベースからそれらのすべてをフェッチし終わるでしょう.
幸いにも、この質問を効率的にする2つの非常に簡単な方法があります.値またはvaluesountリストを使用できます.

value ()を使用して特定のDBカラムを取得する
削除されていないすべてのレコードの名前を表示したいとしましょう.ORMクエリへのわずかな変更を加えることにより、データベースから名前カラムだけを取得できます.
>>> Record.objects.filter(is_deleted=False).values('name')
<QuerySet [{'name': 'First record'}, {'name': 'Second Record'}, {'name': 'Third Record'}]>
見ての通り、レコードオブジェクトのリストを返す代わりに、このQuerySetは名前フィールドだけで構成される辞書のリストを返します.現在のクエリは以下になります.
SELECT name
FROM   records
WHERE  NOT is_deleted; 
value ()メソッドで必要なカラムのリストを提供することで、より多くのカラムを取得できます.
>>> Record.objects.filter(is_deleted=False).values('id', 'name')
<QuerySet [{'id': 1, 'name': 'First record'}, {'id': 2, 'name': 'Second Record'}, {'id': 3, 'name': 'Third Record'}]>

特定のDBカラムを取得するには、values ()を使用します.
これはvalue ()と全く同じように動作します.
>>> Record.objects.filter(is_deleted=False).values_list('name')
<QuerySet [('First record',), ('Second Record',), ('Third Record',)]>
>>>
>>> Record.objects.filter(is_deleted=False).values_list('id', 'name')
<QuerySet [(1, 'First record'), (2, 'Second Record'), (3, 'Third Record')]>
>>>
valuesounds list ()についての気の利いたことは、単一のフィールドに渡す必要がある場合には、フラット= trueパラメータを使用してタプルの代わりに単一の値のリストを返すことができます.
>>> Record.objects.filter(is_deleted=False).values_list('name',flat=True)
<QuerySet ['First record', 'Second Record', 'Third Record']>


クロージングノート
パフォーマンスに関しては、value ()とvaluestriclist ()との間に違いはありません.畝
モデルインスタンスの作成を回避し、特定のフィールドを選択するだけでデータベースクエリをより効率的にする一方で、データのサブセットを取得するための最適化を意図しています.
どちらを使用するかの決定は、どのようなデータ構造体を使用するかによって異なります.畝
通常、タプルよりも直感的な辞書を見つけます.しかし、クエリから1つのフィールドしか必要としない場合、私はvalue = trueという値を使用します.
Originally posted on my blog