QuerySet查询笔记
1. 创建对象
两种方法:
# 创建完必须调用save才保存
a = Blog(name='a', tagline='b')
a.save()
# 一个步骤创建和保存对象
b = Blog.object.create(name='a', tagline=b )
一对多和多对多需使用其他方法
2. 检索对象
通过一个Manager
(系统默认创建,可以用Objects调用它)构建QuerySet
,用以表示一个SELECT语句。
检索所有对象
# 使用Manager的all()方法,返回返回表中所有对象
all_entries = Entry.object.all()
使用过滤器检索特定对象
# filter过滤器,返回包含与给定查找参数匹配的新对象
Entry.objects.filter(pub_date__year=2006)
Entry.objects.all().filter(pub_date__year=2006)
# exclude过滤器,与filter相反,返回不包含给定参数查找匹配的新对象
Entry.objexts.exclude(pub_date__year=2006)
链接过滤器
# 这个QuerySet放回包含以“what"开头的所有条目,这些条目排除了今天,从2015年1月30日到昨天之间发布的条目。
Entry.object.filter(
headline__startswith='what'
).exclude(
pub_date_gte=datetime,date.today()
).filter(
pub_date__gte=datetime.date(2015,1,30))
过滤的QuerySets是独一无二的
每当你精炼一个QuerySet
,你就会得到一个全新的QuerySet
,与以前没有任何关系QuerySet
。每个细化都会创建一个QuerySet
可以存储,使用和重用的独立且不同的细分。
# 这三者QuerySets是分开的。第一个是QuerySet包含所有条目的基础, 其中包含以“What”开头的标题。第二个是第一个的子集,其他标准排除了pub_date今天或将来的记录。第三个是第一个的子集,其他标准仅选择pub_date当前或未来的记录。initial QuerySet(q1)不受细化过程的影响。
q1 = Entry.objects.filter(headline__startswith="What")
q2 = q1.exclude(pub_date__gte=datetime.date.today())
q3 = q1.filter(pub_date__gte=datetime.date.today())
使用get()检索单个对象
# 当查询条件只有一个对象匹配时,可以使用get(),如果结果不为一个会报错
one_entry = Entry.objects.get(pk=1)
QuerySet切片
# 放回查询集合中每个第二个对象的列表,不支持负索引,相当于SQL中的limit和offset子句,禁止对切片查询进行进一步的过滤和排序,会产生模糊性,检索一个对象可以使用具体的[0]索引
Entry.objects.all()[:10:2]
Entry.objects.order_by('headline')[0] # 相当于下面这一句
Entry.objects.order_by('headline')[0:1].get()
字段查找
字段查找是指定SQL WHERE
子句的内容的方式。它们被指定为QuerySet
方法的关键字参数filter()
, exclude()
或者 get()
。
基本查找关键字参数采用表单field__lookuptype=value
。(这是一个双重下划线)。例如:
# 发布时间小于2006-01-01
Entry.objects.filter(pub_date__lte='2006-01-01')
# 查找中指定的字段必须是模型字段的名称。但是有一个例外,如果ForeignKey你可以指定后缀的字段名称_id。在这种情况下,value参数应包含外部模型主键的原始值。例如:
Entry.objects.filter(blog_id=4)
# 精确匹配 exact(),如果查询关键字参数不包含双下划线,则默认使用exact查找,一下2个语句等效
Entry.objects.get(headline__exact='Cat bites dog')
Entry.objects.get(headline='Cat bites dog')
# 使用iexact(),不区分大小写
Bolg.objects.get(name__iexact='beatles blog')
# 使用contains(不区分大小写的icontains )
Entry.objects.get(headline__contains='Lennon')
SELECT ... WHERE headline LIKE '%Lennon%'; # 翻译为sql
# startswith 和 endswith 分别表示以搜索开始和结束,还有不区分大小写的 istartswith 和 iendswith
Blog.objects.filter(headling__startswith='Lennon')
Blog.objects.filter(headling__endswith='dog')
跨越关系的查找
# 主外键自动Join,只需使用跨模型的相关字段的字段名称,如:
Entry.objects.filter(blog_name='Beatles Blog')
# 它也可以倒退。要引用“反向”关系,只需使用模型的小写名称。这个例子检索所有Blog具有至少一个对象Entry ,其headline包含'Lennon':
Blog.objects.filter(entry__headline__contains="Lenno")
主键查询
# 在查询中 pk=id=id__exact 如:
Blog.objects.get(pk=14);
Blog.objects.get(id__exact=14)
Blog.objects.get(id=14)
# 使用pk不仅限于__exact查询 - 可以组合任何查询术语以pk对模型的主键执行查询:
Blog.objects.filter(pk__in=[1,4,7]) # 博客条目id再[1,4,7]三者之间
Blog.objects.filter(pk__gt=14) # 博客条目id大于14
使用Q对象进行查询
使用filter()进行查询,默认是用”AND“将多条语句编辑在一起,如果其他复杂的查询(带OR语句的查询),则可以使用Q()
from django.db.models import Q
# 此语句生成一个 Q 表示两个"question__startswith"查询的“OR”的对象:
Q(question__startswith="What") | Q(question__startswith='Who')
# Q 对象之间可以使用 & | ~ 进行链接,~表示否定
Q(question__startswith='Who') | ~Q(pub_date__year=2005)
# 每个查找函数,采用关键字参数(例如filter(), exclude(), get())也可以通过一个或多个 Q 对象作为位置参数。Q 对象必须位于任何关键字参数的定义之前。即question__startswith='Who',这种之前。
Polls.objects.get(Q(question__startswith="Who"),
Q(pub_date=date(2005,5,2))|
Q(pub_date=date(2005, 5, 6))
) # 这个语句中','相当于 AND,
删除对象
使用delete()方法,删除会遵守SQL约束的行为,如级联删除等
# 删除一个具体的对象
e.delete()
# 批量删除对象,可以使用QuerySet删除
Entry.objects.filter(pub_date__year=2005).delete()
# 删除整个表
Entry.objects.all().delete()
更新对象
# 批量更新对象
Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')
外键表访问主键表
# 使用外键属性访问主表并,可以对外键进行修改并保存
e = Entry.objects.get(id=2)
e.blog = same_blog
e.save
主键表向下访问外键表
# 如果模型具有a ForeignKey,默认情况下,这 Manager是命名的FOO_set,FOO源模型名称是小写的。此Manager返回 QuerySets,其可以被过滤和操纵与上述“检索对象”部分中描述。例如:
b = Blog.objects.get(id=1)
b.entry_set.all() # 返回这条博客的所有记录
b.entry_set.filter(headline__contains='Lennon')
一切其他常用的方法
add(obj1, obj2, ...) # 将特定的模型对象加入关联对象集合。
create(**kwargs) # 创建一个新对象,保存它并将其放入相关的对象集中。返回新创建的对象。
remove(obj1, obj2, ...) # 从相关对象集中删除指定的模型对象。
clear() # 从相关对象集中删除所有对象。
set(objs) # 替换相关对象集。
# 要分配相关集的成员,请将该set()方法与可迭代的对象实例一起使用。例如,if e1和e2是Entry 实例:
b = Blog.objects.get(id=1)
b.entry_set.set([e1, e2])
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
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 __str__(self):
return self.headline