Django SQL データベース 操作 まとめ 入門(3)order_by、values
更新日:2021年2月1日環境:Python3.8.2 Django3.1.5
order_by(*fields)
Entry.objects.filter( pub_date__year=2005 ).order_by( '-pub_date', 'headline' )
上記は、pub_date 降順(DESC), headline 昇順(ASC)の例です。
降順(DESC)はreverse()でできますが、order_by()で降順(DESC)にしたいフィールドに -を付けるだけで簡単に指定できます。
values(*fields, **expressions)
>>> Blog.objects.filter( name__startswith='Beatles' )
<QuerySet [<Blog: Beatles Blog>]>
# This list contains a dictionary.
>>> Blog.objects.filter( name__startswith='Beatles' ).values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
values()に取得したいフィールドを指定してそのフィールドのデータを取得できますが、指定しない場合は上記のように全フィールドの辞書データが取得できます。
全フィールドの場合は、上記のようにvalues()を指定しなくてもBeatles Blogの辞書データで取得できます。
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
>>> Blog.objects.values('id', 'name')
<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]>
上記のように、フィールドを指定('id', 'name')した場合は、そのフィールドのデータのみ取得できます。
values()の引数にオプション追加 **expressions
>>> Blog.objects.values( lower_name=Lower('name') )
<QuerySet [{'lower_name': 'beatles blog'}]>
上記のようにLower()を追加する事により、'Beatles Blog'→'beatles blog'小文字 にしたデータを取得できます。
グループ化して集計数取得
>>> Blog.objects.values( 'entry__authors', entries=Count('entry') )
<QuerySet [{'entry__authors': 1, 'entries': 20}, {'entry__authors': 1, 'entries': 13}]>
>>> Blog.objects.values( 'entry__authors' ).annotate( entries=Count( 'entry' ) )
<QuerySet [{'entry__authors': 1, 'entries': 33}]>
上記のように entryとauthorsモデルを結合して、集計数count()を求める場合は、
先にグループ化annotate()を追加してから、集計数Count('entry')を取得します。
外部キーのデータ取得
<QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
{'name': 'My blog', 'entry__headline': 'Another entry'}, ...]>
OneToOneField、 ForeignKey、またはManyToManyField 属性のデータは
上記のように指定すれば 結合してそのデータを取得できます。
values_list(*fields, flat=False, named=False)
辞書データでなく、リストで値のみ取得する場合はvalues_list()を使用して下さい。
引数のフィールドは、表示したい順('id', 'headline')に記載します。
例
<QuerySet [( 1, 'First entry' ), ...]>
>>> from django.db.models.functions import Lower
>>> Entry.objects.values_list( 'id', Lower( 'headline' ) )
<QuerySet [( 1, 'first entry' ), ...]>
values_list()、flat=True
単一フィールドの場合は、下記のようにflat=Trueを指定すれば、結果をシングル値で取得できます。
例
<QuerySet[(1,), (2,), (3,), ...]>
>>> Entry.objects.values_list( 'id', flat=True ).order_by( 'id' )
<QuerySet [1, 2, 3, ...]>
values_list()、named=True
named=Trueを指定すれば、下記のように結果をPythonのnamedtuple()として取得できます。
例
<QuerySet [Row(id=1, headline='First entry'), ...]>
values_list()、特定のフィールド値1件取得
特定のフィールドの値を1件のみ取得する場合は、values_list()にget()を続けます。
例
'First entry'