Django QuerySet API(Q查询及Q()对象)

xiaoxiao2021-02-28  70

学习Django的时候在这里写了一点数据库创建查询方法 http://blog.csdn.net/u013205877/article/details/76768963 但是比较简单, 在这篇文章比较详细的记录下用法,我挑重要的写,方便自己以后查询复习,更详细的参考:https://www.cnblogs.com/ajianbeyourself/p/3604332.html

例子 blog/models.py

from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def __unicode__(self): # __str__ on Python 3 return self.name class Author(models.Model): name = models.CharField(max_length=50) email = models.EmailField() def __unicode__(self): # __str__ on Python 3 return self.name class Entry(models.Model): blog = models.ForeignKey(Blog) headline = models.CharField(max_length=255) body_text = models.TextField() pub_date = models.DateField() mod_date = models.DateField() authors = models.ManyToManyField(Author) n_comments = models.IntegerField() n_pingbacks = models.IntegerField() rating = models.IntegerField() def __unicode__(self): # __str__ on Python 3 return self.headline

1. QuerySet 创建对象的方法

#一共四种方法 from blog.models import Blog,Author,Entry #第一种 Author.objects.create(name="zhangkun", email="lalalal@qq.com") #第二种 zk = Author(name="zhangkun", email="lalalal@qq.com") zk.save() #第三种 zk = Author() zk.name="zhangkun" zk.email="lalalal@qq.com" zk.save() #第四种 先读,不存在就创建,防止重复 Author.objects.get_or_create(name="zhangkun", email="lalalal@qq.com") # 返回值(object, True/False),创建时返回 True, 已经存在时返回 False

2. QuerySet 获取对象的方法 查询方法

#查询所有的 Person.objects.all() #切面,获取10个,不支持负索引,切片可以节约内存,不支持负索引,后面有相应解决办法,第7条 Persion.objects.all()[:10] #名称为zhangkun的第一条,多条会报错 Person.object.get(name="zhangkun") get只是用来获取第一条对象的,如果需要满足条件的一些人,需要用到filter #名字叫zhangkun的 Person.objects.filter(name="zhangkun") #名字严格叫zhangkun的(这和上一条有啥区别?黑人问好脸.jpg) Person.objects.filter(name__exact="zhangkun") #名字严格叫zhangkun,但是不区分大小写,可以找到Zhangkun,ZHANGKUN,都符合条件 Person.objects.filter(name__iexact="zhangkun") #名字中包含"zhangkun"的 Persin.objects.filter(name__contains="zhangkun") #名字中包含"zhangkun"的,但是不区分大小写 Persin.objects.filter(name__icontains="zhangkun") #正则表达式查询 Person.objects.filter(name__regex="^abc") #不区分大小写的正则 Person.objects.filter(name__iregex="^abc") #排除包含WZ的Person对象 Person.objects.exclude(name__contains="WZ") #找出名称中含有abc但是排除23岁的 Person.objects.filter(name__contains="abc").exclude(age=23)

3.QuerySet 删除符合条件的结果

Person.objects.filter(name__contains="abc").delete() # 删除 名称中包含 "abc"的人 如果写成 people = Person.objects.filter(name__contains="abc") people.delete() 效果也是一样的,Django实际只执行一条 SQL 语句。

4. QuerySet 更新某个内容

1 .批量更新,适用于.all() .filter() .exclude()等等后面

#名称中包含abc的人都更为xxx Person.objects.filter(name__contains="abc").update(name="xxx") #删除所有的Person记录 Person.objects.all().delete()

2.单个的object更新,适用于.get(),get_or_create(),update_or_create()等等得到的obj,和新建很类似

twz = Author.objects.get(name="zhangkun") twz.name = "studyDjango" twz.email="learn@qq.com" twz.save()

5. QuerySet 是可迭代的

#ntry.objects.all() 或者 es 就是 QuerySet 是查询所有的 Entry 条目 es = Entry.objects.all() for e in es: print(e.headline)

(1) 如果只是检查Entry中是否有对象,用Entry.objects.all().exits() (2)QuerySet 支持切片 Entry.objetcs.all()[:10]取出10条,节省内存 (3)用len(Entry.objetcs.all())也能得到Entry的数量,但是推荐使用Entry.objects.count()来查询,因为他用的是SQL:SELECT COUNT(*) (4)list(Entry.objetcs.all()) 可以强行将QuerySet变成列表

6. QuerySet 是可以用pickle序列化到硬盘再读取出来的

#没看懂,有毛用? >>> import pickle >>> query = pickle.loads(s) # Assuming 's' is the pickled string. >>> qs = MyModel.objects.all() >>> qs.query = query # Restore the original 'query'.

7. QuerySet 查询结果排序

作者按照名称排序 Author.objects.all().order_by('name') # 在 column name 前加一个负号,可以实现倒序 Author.objects.all().order_by('-name')

8. QuerySet 支持链式查询

Author.objects.filter(name__contains="zhangkun").filter(email="lalal@qq.com") Author.objects.filter(name__contains="zhangkun").exclude(email="lalal@qq.com") #找到名字含有abc,年纪排除23的 Person.objects.filter(name__contains="abc").exclude(age=23)

9. QuerySet 不支持负索引

Person.objects.all()[:10] 切片操作,前10条 Person.objects.all()[-10:] 会报错!!! #1.使用reverse()解决 Person.objects.all().reverse()[:2]#最后两条 Person.objects.all().reverse()[0]#最后一条 #2.使用order_by,在列名前加一个负号 Author.objects.order_by('-id')[:20]#id最大的20条,相当于从后往前排的20条数据

9. QuerySet 重复的问题,使用 .distinct() 去重

他说,一般的情况下,QuerySet 中不会出来重复的,重复是很罕见的,但是当跨越多张表进行检索后,结果并到一起,可以会出来重复的值,我觉得这可能是设计有问题哈哈哈哈 qs1 = Pathway.objects.filter(label__name='x') qs2 = Pathway.objects.filter(reaction__name='A + B >> C') qs3 = Pathway.objects.filter(inputer__name='WeizhongTu') # 合并到一起 qs = qs1 | qs2 | qs3 这个时候就有可能出现重复的 # 去重方法 qs = qs.distinct()

10.QuerySet 过滤空或者null名称

排除空值和空字符串,首选的方法是链接条件

Author.objects.exclude(name__isnull=True).exclude(name__exact='')

也可以用其他的写法

from django.db.models import Q Author.objects.exclude(Q(name__isnull=True) | Q(exclude(name__exact=''))

推荐看原文:http://code.ziqiangxuetang.com/django/django-queryset-api.html

下面还有: Django QuerySet 进阶内容: http://code.ziqiangxuetang.com/django/django-queryset-advance.html

Django 自定义Field http://code.ziqiangxuetang.com/django/django-custom-field.html

Django 数据表更改 http://code.ziqiangxuetang.com/django/django-schema-migration.html

二、Django中Q查询及Q()对象

一般我们在Django程序中查询数据库操作都是在QuerySet里进行进行,或者将其组合起来,随着我们的程序越来越复杂,查询的条件也跟着复杂起来,这样简单的通过一个filter()来进行查询的条件将导致我们的查询越来越长。Q()对象就是为了将这些条件组合起来。

from django.db.models import Q q=Q(name_startswith="zhangkun")

这样就生成了一个Q()对象,我们可以使用符号&或者|将多个Q()对象组合起来传递给filter(),exclude(),get()等函数。当多个Q()对象组合起来时,Django会自动生成一个新的Q()。例如下面代码就将两个条件组合成了一个:

Q(name_startswith="zhangkun") | Q(name_startswith="zhangkun1")

使用上述代码可以使用SQL语句这么理解(SQL通配符%,替代 0 个或多个字符):

WHERE name LIKE "zhangkun%" OR name LIKE "zhangkun1%"

每个接受关键字参数的查询函数(例如filter()、exclude()、get())都可以传递一个或多个Q 对象作为位置(不带名的)参数。如果一个查询函数有多个Q 对象参数,这些参数的逻辑关系为“AND”。 我们可以在Q()对象的前面使用字符“~”来代表意义“非”:

Q(name_startswith="zhangkun") | ~Q(name_="zhangkun2")

对应SQL语句可以理解为:

WHERE name LIKE "zhangkun%" OR name != "zhangkun1%"

也可以传递多个Q()对象给查询函数:

from django.db.models import Q from biz.volume.models import Volume Volume.objects.get(Q(name__startswith="EBS"),Q(name="AWS") | Q(name="ali"))

多个Q()对象之间的关系Django会自动理解成“且(and)”关系,Q()对象可以结合关键字参数一起传递给查询函数,不过需要注意的是要将Q()对象放在关键字参数的前面,

Volume.objects.get(Q(name__startswith="EBS"),Q(name="AWS") | Q(name="ali"),name=“zhangkun”)
转载请注明原文地址: https://www.6miu.com/read-52321.html

最新回复(0)