Django model select各種クエリー

7538 ワード


 
前言:
最近大神运维コーヒーバーの1篇の文章を见て、ここはただバックアップをして、いろいろなdjango modelの検索を言って、良いことを発见して、とてもこの大神の无私な献身に感谢します.
参照先:https://mp.weixin.qq.com/s/JVh4UnS2Tql9gUVaBSoGuA
きほんそうさ
#       ,  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 

ステップアップオペレーション
# 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         
    User.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  ,            ,     Http404   
    

    実装方法は、次のようになります.
    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