Django model selectの多種の用法の詳しい解

10175 ワード

「Django model updateの様々な使い方の紹介」では、Django modelの様々なupdate操作を紹介しています.この文章は彼女の姉妹編で、Django model selectの使い方を詳しく紹介しています.MySQLに対応したクエリー文を添えて、理解しやすいです.
きほんそうさ

#       ,  SQL:select * from User
User.objects.all()

#   ,  SQL:select * from User where name = '     '
User.objects.filter(name='     ')

#    ,  SQL:select * from User where name != '     '
User.objects.exclude(name='     ')

#       (      ,id  ),  SQL:select * from User where id = 724
User.objects.get(id=123)

一般的な操作

#     ,  SQL:select count(1) from User
User.objects.count()

#     ,  SQL:select count(1) from User where name = '     '
User.objects.filter(name='     ').count()

#   ,>,  SQL:select * from User where id > 724
User.objects.filter(id__gt=724)

#     ,>=,  SQL:select * from User where id >= 724
User.objects.filter(id__gte=724)

#   , 1 and id < 10
User.objects.filter(id__gt=1, id__lt=10)

#   ,in,  SQL:select * from User where id in (11,22,33)
User.objects.filter(id__in=[11, 22, 33])

#    ,not in,  SQL:select * from User where id not in (11,22,33)
User.objects.exclude(id__in=[11, 22, 33])

#   :isnull=True,  SQL:select * from User where pub_date is null
User.objects.filter(pub_date__isnull=True)

#    :isnull=False,  SQL:select * from User where pub_date is not null
User.objects.filter(pub_date__isnull=True)

#   ,like,     ,  SQL:select * from User where name like '%sre%',SQL       
User.objects.filter(name__contains="sre")

#   ,like,      ,  SQL:select * from User where name like '%sre%',SQL       
User.objects.filter(name__icontains="sre")

#    ,     ,  SQL:select * from User where name not like '%sre%',SQL       
User.objects.exclude(name__contains="sre")

#    ,      ,  SQL:select * from User where name not like '%sre%',SQL       
User.objects.exclude(name__icontains="sre")

#   ,between and,  SQL:select * from User where id between 3 and 8
User.objects.filter(id__range=[3, 8])

#      ,     ,  SQL:select * from User where name like 'sh%',SQL       
User.objects.filter(name__startswith='sre')

#      ,      ,  SQL:select * from User where name like 'sh%',SQL       
User.objects.filter(name__istartswith='sre')

#      ,     ,  SQL:select * from User where name like '%sre',SQL       
User.objects.filter(name__endswith='sre')

#      ,      ,  SQL:select * from User where name like '%sre',SQL       
User.objects.filter(name__iendswith='sre')

#   ,order by,  ,  SQL:select * from User where name = '     ' order by id
User.objects.filter(name='     ').order_by('id')

#     ,order by,  name      ,  name      id    
User.objects.filter(name='     ').order_by('name','-id')

#   ,order by,  ,  SQL:select * from User where name = '     ' order by id desc
User.objects.filter(name='     ').order_by('-id')

ステップアップオペレーション

# limit,  SQL:select * from User limit 3;
User.objects.all()[:3]

# limit,         ,     SQL,    :select * from User limit 3,10000000,  3      , 10000000 (10000000        )
User.objects.all()[3:]

# offset,      10-20   (   10,  20),     SQL,     SQL  
User.objects.all()[10:20]

#   ,group by,  SQL:select username,count(1) from User group by username;
from django.db.models import Count
User.objects.values_list('username').annotate(Count('id'))

#   distinct,  SQL:select distinct(username) from User
User.objects.values('username').distinct().count()

# filter  、    ,  SQL:select username,fullname from accounts_user
User.objects.values_list('username', 'fullname')

# filter  、    ,  values_list         ,               ,       ,    flat      ,                     ,           
User.objects.values_list('username', flat=True)

# int      、   、  、   
from django.db.models import Sum,Count,Max,Min,Avg

User.objects.aggregate(Count(‘id'))
User.objects.aggregate(Sum(‘age'))

時間フィールド

#     ,date
User.objects.filter(create_time__date=datetime.date(2018, 8, 1))
User.objects.filter(create_time__date__gt=datetime.date(2018, 8, 2))

#    ,year
User.objects.filter(create_time__year=2018)
User.objects.filter(create_time__year__gte=2018)

#    ,month
User.objects.filter(create_time__month__gt=7)
User.objects.filter(create_time__month__gte=7)

#    ,day
User.objects.filter(create_time__day=8)
User.objects.filter(create_time__day__gte=8)

#    ,week_day
 User.objects.filter(create_time__week_day=2)
User.objects.filter(create_time__week_day__gte=2)

#    ,hour
User.objects.filter(create_time__hour=9)
User.objects.filter(create_time__hour__gte=9)

#    ,minute
User.objects.filter(create_time__minute=15)
User.objects.filter(create_time__minute_gt=15)

#    ,second
User.objects.filter(create_time__second=15)
User.objects.filter(create_time__second__gte=15)


#       
today = datetime.date.today()
select = {'day': connection.ops.date_trunc_sql('day', 'create_time')}
deploy_date_count = Task.objects.filter(
 create_time__range=(today - datetime.timedelta(days=7), today)
).extra(select=select).values('day').annotate(number=Count('id'))

Qの使用
Qオブジェクトはキーワードパラメータをカプセル化することができ,複数のクエリーをよりよく適用し,&(and)、|(or)、~(not)オペレータを組み合わせることができる.
たとえば下の文

from django.db.models import Q

User.objects.filter(
 Q(role__startswith='sre_'),
 Q(name='   ') | Q(name='     ')
)

SQL文に変換するには、次のようにします.
select * from User where role like 'sre_%' and(name='公衆番号'or name='運維コーヒーバー')
通常、フロント検索ボックスに文字を入力したり、バックグラウンドでデータベースにタイトルやコンテンツを検索したりするなど、Qを検索ロジックとして使用します.

_s = request.GET.get('search')

_t = Blog.objects.all()
if _s:
 _t = _t.filter(
 Q(title__icontains=_s) |
 Q(content__icontains=_s)
 )

return _t

外部キー:ForeignKey
テーブル構造:

class Role(models.Model):
 name = models.CharField(max_length=16, unique=True)


class User(models.Model):
 username = models.EmailField(max_length=255, unique=True)
 role = models.ForeignKey(Role, on_delete=models.CASCADE)

順方向クエリー:
#ユーザーのロール名を問い合わせる_t = User.objects.get(username='運維コーヒーバー')t.role.name
逆クエリー:
#クエリーロールの下に含まれるすべてのユーザー_t = Role.objects.get(name='Role03') _t.user_set.all()
別の逆クエリー方法:
_t = Role.objects.get(name='Role03')
前の方法よりsetのメソッドはクエリ速度が速くなります.objects.filter(role=_t)
3つ目の逆クエリの方法:
外部キーフィールドにrelated_がある場合nameプロパティ、たとえばmodelsは次のとおりです.

class User(models.Model):
 username = models.EmailField(max_length=255, unique=True)
 role = models.ForeignKey(Role, on_delete=models.CASCADE,related_name='roleUsers')

ではrelated_を直接使えますnameプロパティがロールに取得されたすべてのユーザー
_t = Role.objects.get(name = 'Role03') _t.roleUsers.all()
M2M:ManyToManyField
テーブル構造:
class Group(models.Model): name = models.CharField(max_length=16, unique=True)
class User(models.Model): username = models.CharField(max_length=255, unique=True) groups = models.ManyToManyField(Group, related_name='groupUsers')
順方向クエリー:
#ユーザーの所属グループを問い合わせる_t = User.objects.get(username='運維コーヒーバー')t.groups.all()
逆クエリー:
#クエリー・グループにユーザーが含まれています_t = Group.objects.get(name = 'groupC') _t.user_set.all()
同じM 2 Mフィールドにrelated_がある場合name属性は、下の方で直接チェックできます
_t = Group.objects.get(name = 'groupC') _t.groupUsers.all()
get_object_or_404
通常、データベースでデータを検索する場合は、次の方法を使用します.
_t = User.objects.get(id=734)
ただしid=724のデータが存在しない場合、プログラムはエラーを投げ出す
abcer.models.DoesNotExist: User matching query does not exist.
プログラムの互換性と異常判断のために、次の2つの方法を使用できます.
方法一:getをfilterに変更する
_t = User.objects.filter(id=724)#取り出し_t後に判断する_tが存在するかどうか
方法2:get_を使用するobject_or_404
from django.shortcuts import get_object_or_404
_t = get_object_or_404(User, id=724) # get_object_or_404メソッドは、djangoのgetメソッドを先に呼び出し、クエリのオブジェクトが存在しない場合、Http 404の例外を放出する
実装方法は、次のようになります.

from django.http import Http404

try:
 _t = User.objects.get(id=724)
except User.DoesNotExist:
 raise Http404
get_or_create

名前の通り、オブジェクトが存在しない場合は、次のように作成されます.
object, created = User.objects.get_or_create(username='運維コーヒーバー')
objectとcreatedからなるメタグループを返します.objectはクエリーされたオブジェクトまたは作成されたオブジェクトであり、createdは新しいオブジェクトが作成されたかどうかを示すブール値です.
実装方法は、次のようになります.

try:
 object = User.objects.get(username='     ')
 created = False
exception User.DoesNoExist:
 object = User(username='     ')
 object.save()

 created = True

returen object, created

オリジナルSQLの実行
Djangoの中でORMを使うことができるのはそれのORMを使うようにしましょう、原生のSQLを実行することを提案しないで、いくつか安全な問題があるかもしれなくて、もし本当にSQLが複雑すぎてORMが実現できないならば、それでは下で原生のSQLを実行する方法を見て、直接pymysqlを使うこととほぼ一致しました

from django.db import connection

with connection.cursor() as cursor:
 cursor.execute('select * from accounts_User')
 row = cursor.fetchall()

return row

注意ここの表の名前はapp名+下線+model名の方式を使います