Django 数据库操作详解(3)

这样意味着数据库查询会执行两次,实际两次数据库加载
为了避免这个问题,简单保存QuerySet复用

queryset = Poll.objects.all() print [p.headline for p in queryset] # Evaluate the query set. print [p.pub_date for p in queryset] # Re-use the cache from the evaluation.

通过Q对象进行复合查询

关键字查询使用filter 是 and集合,如果你想要执行更多的复合查询如“or”可以Q对象。
Q对象(django.db.models.Q)是一个关键字集合封装的参数。
例如

Q(question__startswith='What')

Q对象可以使用 & 和 |链接
例如一个OR查询

Q(question__startswith='Who') | Q(question__startswith='What')

相当于下面的SQL
Sql代码 收藏代码
WHERE question LIKE ‘Who%’ OR question LIKE ‘What%’
取消一个Q对象使用~

Q(question__startswith='Who') | ~Q(pub_date__year=2005)

可以传入多个Q对象

Poll.objects.get( Q(question__startswith='Who'), Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)) )

翻译成SQL
SELECT * from polls WHERE question LIKE ‘Who%’
AND (pub_date = ‘2005-05-02’ OR pub_date = ‘2005-05-06’)

比较对象

比较两个模型实例,使用python标准的运算符,两个等号==

some_entry == other_entry some_entry.id == other_entry.id some_obj == other_obj some_obj.name == other_obj.name

删除对象

删除方法是很方便的,方法名为delete(),这个方法直接删除对象没有返回值
例如

e.delete()

你也可以批量删除对象,每个QuerySet有一个delete()方法,能删除QuerySet里所有对象
例如:删除pub_date为2005年的对象

一次修改多个对象

有时候你想给QuerySet里所有对象的一个字段赋予特定值,你可以使用update()方法
例如

# Update all the headlines with pub_date in 2007. Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')

这个方法只能用于无关联字段和外键

b = Blog.objects.get(pk=1) # Change every Entry so that it belongs to this Blog. Entry.objects.all().update(blog=b)

update()方法不返回任何值,QuerySet不支持save方法,如果要执行save,可以如下:

for item in my_queryset: item.save()

update也可以使用F()

# THIS WILL RAISE A FieldError Entry.objects.update(headline=F('blog__name'))

关系对象

当你在model里定义一个关系时,模型实例会有一个方便的API来访问关系对象。用本页上面的模型举个例子,一个Entry
对象可以得到blog对象,访问blog属性e.blog。
django也创建API来访问关系对象的另一边,一个blog对象访问Entry列表

b.entry_set.all().

One-to-many关系

如果一个对象有ForeignKey,这个模型实例访问关系对象通过简单的属性

e = Entry.objects.get(id=2) e.blog # Returns the related Blog object.

你可以凭借外键属性获取和赋值,修改外键值知道执行save()方法才会保存到数据库

e = Entry.objects.get(id=2) e.blog = some_blog e.save()

如果ForeignKey 设置了null=True 你可以赋值为None

e = Entry.objects.get(id=2) e.blog = None e.save() # "UPDATE blog_entry SET blog_id = NULL ...;" e = Entry.objects.get(id=2) print e.blog # Hits the database to retrieve the associated Blog. print e.blog # 不会在向数据库取; 使用缓存中的值. e = Entry.objects.select_related().get(id=2) print e.blog # 不会在向数据库取; 使用缓存中的值. print e.blog # 不会在向数据库取; 使用缓存中的值. b = Blog.objects.get(id=1) b.entry_set.all() # 返回所有blog的关联对象. # b.entry_set is a Manager that returns QuerySets. b.entry_set.filter(headline__contains='Lennon') b.entry_set.count() b = Blog.objects.get(id=1) b.entries.all() # 返回所有blog的关联对象 # b.entries is a Manager that returns QuerySets. b.entries.filter(headline__contains='Lennon') b.entries.count() add(obj1, obj2, ...)增加多个关系对象 create(**kwargs)建立新对象 remove(obj1, obj2, ...)去除多个关系对象 clear()清理所有关系对象 b = Blog.objects.get(id=1) b.entry_set = [e1, e2] Many-to-many关系 e = Entry.objects.get(id=3) e.authors.all() # 返回Entry所有authors . e.authors.count() e.authors.filter(name__contains='John') a = Author.objects.get(id=5) a.entry_set.all() # 返回Author所有entry . #One-to-one关系 class EntryDetail(models.Model): entry = models.OneToOneField(Entry) details = models.TextField() ed = EntryDetail.objects.get(id=2) ed.entry # 返回 Entry 对象.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9607415a0529018a0f6f2981af8fc786.html