Django学习笔记1

root
abc abc

由于对 queryset 切片工作方式的模糊性,禁止对其进行进一步的排序或过滤。
https://docs.djangoproject....

要检索 单个 对象而不是列表(例如,SELECT foo FROM bar LIMIT 1),请使用索引而不是切片。例如,这会按标题的字母顺序返回数据库中的第一个 Entry:

Entry.objects.order_by("headline")[0]

字段查询即你如何制定 SQL WHERE 子句。它们以关键字参数的形式传递给 QuerySet 方法 filter(), exclude() 和 get()。

基本的查找关键字参数采用形式 field__lookuptype=value (使用双下划线)。例如:

Entry.objects.filter(pub_date__lte="2006-01-01")

若你未提供查询类型 —— 也就说,若关键字参数未包含双下划线 —— 查询类型会被指定为 exact。

例如,以下两个语句是等价的:

Blog.objects.get(idexact=14) # Explicit form
Blog.objects.get(id=14) #
exact is implied
这是为了方便,因为 exact 查询是最常见的。

iexact
不区分大小写的匹配。因此,查询:

Blog.objects.get(name__iexact="beatles blog")

contains
大小写敏感的包含测试。例子:

Entry.objects.get(headline__contains="Lennon")
粗略地转为 SQL:

SELECT ... WHERE headline LIKE '%Lennon%';
注意这将匹配标题 'Today Lennon honored',而不是 'today lennon honored'。

这也有个大小写不敏感的版本, icontains。

startswith, endswith
以……开头和以……结尾的查找。当然也有大小写不敏感的版本,名为 istartswith 和 iendswith。

同样,这只介绍了皮毛。

(假设有个关联的 Author 模型),若某项条目没有任何关联的 author,它会被视作没有关联的 name,而不是因为缺失 author 而抛出错误。大多数情况下,这就是你期望的。唯一可能使你迷惑的场景是在使用 isnull 时。因此:

Blog.objects.filter(entryauthorsname__isnull=True)
将会返回 Blog 对象,包含 author 的 name 为空的对象,以及那些 entry 的 author 为空的对象。若你不想要后面的对象,你可以这样写:

Blog.objects.filter(entryauthorsisnull=False, entryauthorsname__isnull=True)

要选择所有包含 2008 年至少一个标题中有 "Lennon" 的条目的博客(满足两个条件的同一条目),我们要写:

Blog.objects.filter(entryheadlinecontains="Lennon", entrypub_dateyear=2008)
否则,如果要执行一个更为宽松的查询,选择任何只在标题中带有 "Lennon" 的条目和 2008 年的条目的博客,我们将写:

Blog.objects.filter(entryheadlinecontains="Lennon").filter(
entrypub_dateyear=2008
)
假设只有一个博客既有包含 "Lennon" 的条目又有 2008 年的条目,但 2008 年的条目中没有包含 "Lennon" 。第一个查询不会返回任何博客,但第二个查询会返回那一个博客。(这是因为第二个过滤器选择的条目可能与第一个过滤器中的条目相同,也可能不相同)。我们是用每个过滤器语句来过滤 Blog 项,而不是 Entry 项)。简而言之,如果每个条件需要匹配相同的相关对象,那么每个条件应该包含在一个 filter() 调用中。

但是,与 filter() 的行为不同,其并不会限制博客同时满足这两种条件。要这么做的话,也就是筛选出所有条目标题不带 "Lennon" 且发布年不是 2008 的博客,你需要做两次查询:

Blog.objects.exclude(
entryin=Entry.objects.filter(
headline
contains="Lennon",
pub_date__year=2008,
),
)