基本操作 1 2 3 4 5 6 7 8 9 10 11 User.objects.all () User.objects.filter (name='Uzi' ) User.objects.exclude(name='Uzi' ) User.objects.get(id =123 )
常用操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 User.objects.count() User.objects.filter (name='Uzi' ).count() User.objects.filter (id__gt=724 ) User.objects.filter (id__gt=1 , id__lt=10 ) User.objects.filter (id__in=[11 , 22 , 33 ]) User.objects.exclude(id__in=[11 , 22 , 33 ]) User.objects.filter (pub_date__isnull=True ) User.objects.filter (name__contains="sre" ) User.objects.exclude(name__contains="sre" ) User.objects.filter (id__range=[3 , 8 ]) User.objects.filter (name='Uzi' ).order_by('id' ) User.objects.filter (name='Uzi' ).order_by('-id' ) User.objects.filter (name='Uzi' ).order_by('name' ,'-id' )
进阶操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 User.objects.all ()[:3 ] User.objects.all ()[3 :] User.objects.all ()[10 :20 ]from django.db.models import Count User.objects.values_list('username' ).annotate(Count('id' )) User.objects.values('username' ).distinct().count() User.objects.values_list('username' , 'fullname' ) User.objects.values_list('username' , flat=True )from django.db.models import Sum,Count,Max,Min,Avg User.objects.aggregate(Count(‘id ’)) User.objects.aggregate(Sum(‘age’))
时间字段 1 2 3 4 5 6 7 8 9 10 11 12 13 14 User.objects.filter (create_time__date=datetime.date(2018 , 8 , 1 )) User.objects.filter (create_time__date__gt=datetime.date(2018 , 8 , 2 )) User.objects.filter (create_time__year=2018 ) User.objects.filter (create_time__year__gte=2018 ) 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)操作符。
例如下边的语句
1 2 3 4 5 6 from django.db.models import Q User.objects.filter ( Q(role__startswith='sre_' ), Q(name='公众号' ) | Q(name='Uzi' ) )
1 select * from User where role like 'sre_%' and (name= '公众号' or name= 'Uzi' )
1 2 通常更多的时候我们用Q来做搜索逻辑,比如前台搜索框输入一个字符,后台去数据库中检索标题或内容中是否包含
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 _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)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 正向查询: _t = User.objects.get(username='Uzi' ) _t.role.name 反向查询: _t = Role.objects.get(name='Role03' ) _t.user_set.all () 另一种反向查询的方法: _t = Role.objects.get(name='Role03' ) User.objects.filter (role=_t) 第三种反向查询的方法: 如果外键字段有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 = 'Uzi' ) _t.groups.all () 反向查询: _t = Group.objects.get(name = 'groupC' ) _t.user_set.all () 同样M2M字段如果有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. 为了程序兼容和异常判断,我们可以使用下边两种方式: 方式一:get改为filter _t = User.objects.filter (id =724 ) 方式二:使用get_object_or_404from django.shortcuts import get_object_or_404 _t = get_object_or_404(User, id =724 ) 实现方法类似于下边这样:from django.http import Http404try : _t = User.objects.get(id =724 )except User.DoesNotExist: raise Http404 get_or_create 顾名思义,查找一个对象如果不存在则创建,如下:object , created = User.objects.get_or_create(username='Uzi' ) 返回一个由object 和created组成的元组,其中object 就是一个查询到的或者是被创建的对象,created是一个表示是否创建了新对象的布尔值 实现方式类似于下边这样:try : object = User.objects.get(username='Uzi' ) created = False exception User.DoesNoExist: object = User(username='Uzi' ) object .save() created = True returen object , created 执行原生SQL Django中能用ORM的就用它ORM吧,不建议执行原生SQL,可能会有一些安全问题,如果实在是SQL太复杂ORM实现不了,那就看看下边执行原生SQL的方法,跟直接使用pymysql基本一致了from django.db import connectionwith connection.cursor() as cursor: cursor.execute('select * from accounts_User' ) row = cursor.fetchall()return row 注意这里表名字要用app名+下划线+model名的方式