Django-1.11中文文档——操作关联对象
关联对象参考
写在最前面——基础示例模型如下:
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self): # __unicode__ on Python 2
return self.name
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self): # __unicode__ on Python 2
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): # __unicode__ on Python 2
return self.headline
class RelatedManager
用在一对多或者多对多关系中的管理器。存在于以下两种情况:
ForeignKey外键关系的另一端:
from django.db import models
class Reporter(models.Model):
# ...
pass
class Article(models.Model):
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
下文的方法对于上面示例中的reporter.article_set管理器是有效的。
ManyToMany关系的两端:
class Topping(models.Model):
# ...
pass
class Pizza(models.Model):
toppings = models.ManyToManyField(Topping)
下文的方法对于上面示例中的topping.pizza_set管理器和pizza.toppings管理器都是有效的。
add(*objs,bulk=True)
将指定模型对象加到相关对象集中。示例:
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.add(e) # Associates Entry e with Blog b.
在上面的示例中,外键关系的add()方法用QuerySet.update()来实施更新。这要求对象是已保存的。
当设置bulk=False时,则调用e.save()来实施更新。
当多对多关联对象使用add()方法时,并不调用save()方法,而是使用QuerySet.bulk_create()来创建关联。如果你在创建关联时需要执行一些自定义的逻辑,请查看m2m_changed 。
create(**kwargs)
创建一个新对象,保存并将它加入到关联对象集中。返回新创建的对象:
>>> b = Blog.objects.get(id=1)
>>> e = b.entry_set.create(
... headline='Hello',
... body_text='Hi',
... pub_date=datetime.date(2005, 1, 1)
... )
# 这里不必调用 e.save() -- 它已经被保存了。
相当于:
>>> b = Blog.objects.get(id=1)
>>> e = Entry(
... blog=b,
... headline='Hello',
... body_text='Hi',
... pub_date=datetime.date(2005, 1, 1)
... )
>>> e.save(force_insert=True)
注意,不需要为关联模型指定关键字参数。在上面的示例中,没有传入blog参数到create()方法`中,因为Django已经知道新Entry对象的blog字段应设置为b。
remove(*objs)
将指定的模型对象从关联对象集中移除:
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
与add()类似,示例中调用了e.save()实施更新。而多对多关系使用remove()方法时,使用QuerySet.delete()删除关联。如果你在删除关联时需要执行一些自定义的逻辑,请查看m2m_changed 。
对于ForeignKey对象,只有null=True时本方法才有效。如果外键不允许为空,那么在关联到另一个模型前不能被删除。在上面的示例中,从b.entry_set()删除e相当于设置e.blog=None ,而由于blog的外键没有设置null=True,所以这是无效的。
对于外键对象,本方法接收bulk参数来控制怎么实施操作。如果为True (默认值),使用QuerySet.update() ;如果为False ,则每个单独的模型实例调用save()方法。这会触发pre_save和post_save信号,并会有性能开销。
clear()
移除关联对象集中的所有对象:
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()
注意,这并没有删除关联对象——只是消除了关联。
类似与remove() ,对于外键关系,只有null=True时,clear()才有效,它同样也接收bulk关键字参数。
set(objs, bulk=True, clear=False)
替换关联对象:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set.set(new_list)
本方法接收一个clear参数来控制操作方式。如果为False (默认值),先比较新旧对象集,在新对象集中没有的对象会用remove()从旧对象集中移除掉,然后只增加新旧对象不重叠的对象;如果为True ,则用clear()方法清楚所有旧对象集,然后一次性加入整个新对象集。
bulk参数会传入add()方法。
注意,由于set()是一个混合操作,它服从于竞争条件(race conditions)。例如,同时调用clear()和add(),但是结果可能是新对象被添加到数据库中。
译者注:竞争条件
竞争条件指多个线程或者进程在读写一个共享数据时结果依赖于它们执行的相对时间的情形。
竞争条件发生在当多个进程或者线程在读写数据时,其最终的的结果依赖于多个进程的指令执行顺序。
例如:考虑下面的例子
假设两个进程P1和P2共享了变量a。在某一执行时刻,P1更新a为1,在另一时刻,P2更新a为2。
因此两个任务竞争地写变量a。在这个例子中,竞争的“失败者”(最后更新的进程)决定了变量a的最终值。
多个进程并发访问和操作同一数据且执行结果与访问的特定顺序有关,称为竞争条件。
注意
对所有种类的关联字段,
add(),create(),remove(),clear(),和set()都会立即应用更改,不必在任何一端再调用save()。另外,如果使用的是多对多关系的媒介模型,
add(),create(),remove()和set()方法是无效的。如果使用
prefetch_related(),add(),remove(),clear(),和set()会清除吊缓存。
直接赋值
通过将一个新的可迭代对象赋值给关联对象集,可以批量替换掉旧的对象集:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
如果外键关系设置了null=True ,那么再添加新列表之前,关联管理器将首先解除原有对象集中对象的关联。否则的话,新的列表将加入到原有的对象集。
以下1.10版中的用法已废弃:
>>> e.related_set.set([obj1, obj2, obj3])
Django-1.11中文文档——操作关联对象的更多相关文章
- Django 1.10中文文档-第一个应用Part2-模型和管理站点
本教程继续Part1.我们将设置数据库,创建您的第一个模型,并快速介绍Django的自动生成的管理网站. 数据库设置 现在,编辑mysite/settings.py.它是一个用模块级别变量表示Djan ...
- Django 1.10中文文档-执行查询
Django 1.10中文文档: https://github.com/jhao104/django-chinese-doc 只要创建好 数据模型, Django 会自动为生成一套数据库抽象的API, ...
- Django 1.10中文文档-聚合
Django 数据库抽象API 描述了使用Django 查询来增删查改单个对象的方法. 然而,有时候你要获取的值需要根据一组对象聚合后才能得到. 这个主题指南描述了如何使用Django的查询来生成和返 ...
- Django 1.10中文文档-第一个应用Part7-自定义管理站点
开发第一个Django应用,Part7 本教程上接Part6.将继续完成这个投票应用,本节将着重讲解如果用Django自动生成后台管理网站. 自定义管理表单 通过admin.site.register ...
- Django 1.10中文文档-第一个应用Part5-测试
本教程上接教程Part4. 前面已经建立一个网页投票应用,现在将为它创建一些自动化测试. 自动化测试简介 什么是自动化测试 测试是检查你的代码是否正常运行的行为.测试也分为不同的级别.有些测试可能是用 ...
- Django 1.10中文文档-第一个应用Part3-视图和模板
本教程上接Django 1.10中文文档-第一个应用Part2-模型和管理站点.我们将继续开发网页投票这个应用,主要讲如何创建一个对用户开放的界面. 概览 视图是Django应用中的一“类”网页,它通 ...
- Django 1.10中文文档—第一个Django应用Part1
在本教程中,我们将引导您完成一个投票应用程序的创建,它包含下面两部分: 一个可以进行投票和查看结果的公开站点: 一个可以进行增删改查的后台admin管理界面: 我们假设你已经安装了Django.您可以 ...
- Django REST framework 中文文档
Django REST framework介绍 现在前后端分离的架构设计越来越流行,业界甚至出现了API优先的趋势. 显然API开发已经成为后端程序员的必备技能了,那作为Python程序员特别是把Dj ...
- Django 1.10中文文档-第一个应用Part6-静态文件
本教程上接Part5 .前面已经建立一个网页投票应用并且测试通过,现在主要讲述如何添加样式表和图片. 除由服务器生成的HTML文件外,网页应用一般还需要提供其它必要的文件——比如图片.JavaScri ...
随机推荐
- C++typename的由来和用法
- 基于Qt的tcp客户端和服务器实现摄像头帧数据处理(客户端部分)
项目简述 实现客户端调用摄像头,并以帧的形式将每一帧传输到服务端,服务端将图片进行某些处理后再返回给客户端.(客户端与服务端通信代码部分参考<Qt5 开发及实例>) 项目步骤 客户端的编写 ...
- JVM之JVM体系结构
JVM是运行在操作系统之上的,它与硬件没有直接的交互 下图运行时数据区灰色代表线程私有,亮色(方法区和堆)代表所有线程共享. 1.类装载器ClassLoader 负责加载class文件,class文件 ...
- Java程序操作HDFS
1.新建项目2.导包 解压hadoop-2.7.3.tar.gzE:\工具\大数据\大数据提升资料\01-软件资料\06-Hadoop\安装包\Java1.8环境下编译\hadoop-2.7.3\ha ...
- Codeforces Round #594 (Div. 2) D1 - The World Is Just a Programming Task (贪心)
思路:枚举换的位置i,j 然后我们要先判断改序列能否完全匹配 如果可以 那我们就需要把差值最大的位置换过来 然后直接判断就行
- XHXJ's LIS HDU - 4352 最长递增序列&数位dp
代码+题解: 1 //题意: 2 //输出在区间[li,ri]中有多少个数是满足这个要求的:这个数的最长递增序列长度等于k 3 //注意是最长序列,可不是子串.子序列是不用紧挨着的 4 // 5 // ...
- C#异步和多线程以及Thread、ThreadPool、Task区别和使用方法
本文的目的是为了让大家了解什么是异步?什么是多线程?如何实现多线程?对于当前C#当中三种实现多线程的方法如何实现和使用?什么情景下选用哪一技术更好? 第一部分主要介绍在C#中异步(async/awai ...
- 头疼的Python 脚本报错
Python 脚本报错 检查是否用了制表符.变量声明前面不能用制表符,只能用空格,版本为2.7.14
- 洛谷 P4143 采集矿石 后缀数组
题目背景 ZRQ 成功从坍塌的洞穴中逃了出来.终于,他看到了要研究的矿石.他想挑一些带回去完成任务. 题目来源:Zhang_RQ哦对了 \(ZRQ\) 就他,嗯 题目描述 ZRQ 发现这里有 \(N\ ...
- leetcode11 盛水容器 贪心
这道题,总感觉做过... 先理解题意,何为容器 容器 要求水面高度相同 于是体积就是长方形,高度有两块较高板的低板决定,宽度由两块板间距离决定. 考虑当前最优解,就贪心 从两边开始向内,若能使得体积变 ...