Django - 回顾(2)- 中介模型
一、中介模型
我们之前学习图书管理系统时,设计了Publish、Book、Author、AuthorDetail这样几张表,其中Book表和Author表是多对多关系,处理类似这样简单的多对多关系时,使用标准的ManyToManyField就可以了。但是,有时你可能需要关联数据到两个模型之间的关系上。
例如,有这样一个应用,它记录音乐家所属的音乐小组。我们可以用一个ManyToManyField 表示小组和成员之间的多对多关系。但是,有时你可能想知道更多成员关系的细节,比如成员是何时加入小组的。
对于这些情况,Django 允许你指定一个中介模型来定义多对多关系。 你可以将其他字段放在中介模型里面。原模型的ManyToManyField 字段将使用through 参数指向中介模型。对于上面的音乐小组的例子,代码如下:
from django.db import models class Person(models.Model):
name = models.CharField(max_length=128) def __str__(self): # __unicode__ on Python 2
return self.name class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField("Person", through='Membership') def __str__(self): # __unicode__ on Python 2
return self.name class Membership(models.Model):
person = models.ForeignKey("Person", on_delete=models.CASCADE)
group = models.ForeignKey("Group", on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
既然你已经设置好ManyToManyField 来使用中介模型(在这个例子中就是Membership),接下来你要开始创建多对多关系。你要做的就是创建中介模型的实例:
>>> ringo = Person.objects.create(name="Ringo Starr") # 创建一个音乐家ringo
>>> paul = Person.objects.create(name="Paul McCartney") # 创建一个音乐家paul
>>> beatles = Group.objects.create(name="The Beatles") # 创建一个音乐小组beatles
>>> m1 = Membership(person=ringo, group=beatles,
... date_joined=date(1962, 8, 16),
... invite_reason="Needed a new drummer.") # 创建一个中介模型的实例
>>> m1.save()
>>> beatles.members.all() # 多对多的正向查询语法
[<Person: Ringo Starr>]
>>> ringo.group_set.all() # 多对多的反向查询语法
[<Group: The Beatles>]
>>> m2 = Membership.objects.create(person=paul, group=beatles,
... date_joined=date(1960, 8, 1),
... invite_reason="Wanted to form a band.") # 创建一个中介模型的实例
>>> beatles.members.all() # 多对多的正向查询语法
[<Person: Ringo Starr>, <Person: Paul McCartney>]
注意:与普通的多对多字段不同,不能使用add、create和赋值语句(比如,beatles.members = [...])来创建关系:
# THIS WILL NOT WORK
>>> beatles.members.add(john)
# NEITHER WILL THIS
>>> beatles.members.create(name="George Harrison")
# AND NEITHER WILL THIS
>>> beatles.members = [john, paul, ringo, george]
为什么不能这样做?这是因为你不能只创建 Person和 Group之间的关联关系,你还要指定 Membership模型中所需要的所有信息(比如date_joined和invite_reason);而简单的add、create 和赋值语句是做不到这一点的。所以它们不能在使用中介模型的多对多关系中使用。此时,唯一的办法就是创建中介模型的实例。
remove()方法被禁用也是出于同样的原因。但是clear()方法却是可用的。它可以清空某个实例所有的多对多关系:
# Beatles have broken up
>>> beatles.members.clear()
# Note that this deletes the intermediate model instances
>>> Membership.objects.all()
[]
Django - 回顾(2)- 中介模型的更多相关文章
- Django QuerySet和中介模型
笔记如下 一.QuerySet QuerySet是什么? 类似列表里边存着对象 只和ORM有关系 from app01.models import Book def qDemo(request): b ...
- Django进阶之QuerySet和中介模型
QuerySet QuerySet是查询集,就是传到服务器上的url里面的查询内容.其形态类似于Python的列表,列表中的元素是QuerySet对象.支持大部分列表的内置方法. 可切片 QueryS ...
- Django框架 之 ORM中介模型
Django框架 之 ORM中介模型 中介模型 处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的ManyToManyField 就可以了.但是,有时你可能需要关联数据 ...
- django中介模型,CBV模型,及logging日志配制
1.中介模型 中介模型,这个是在我们创建表格时,多对多添加的时候应用到的,通过制定ManyToManyField字段中的through参数来定义,为两者的关系新建一个中介class 为什么会产生这个中 ...
- Django【第26篇】:中介模型以及优化查询以及CBV模式
中介模型以及优化查询以及CBV模式 一.中介模型:多对多添加的时候用到中介模型 自己创建的第三张表就属于是中介模型 class Article(models.Model): ''' 文章表 ''' t ...
- Orm之中介模型
什么是中介模型 中介模型针对的是ManyToMany(多对多)的时候第三张表的问题, 中介模型其实指的就是我们不通过Django创建第三张表,如果自己不创建第三张表,而是由django给我们创建,那就 ...
- 中介模型以及优化查询以及CBV模式
一.中介模型:多对多添加的时候用到中介模型 自己创建的第三张表就属于是中介模型 class Article(models.Model): ''' 文章表 ''' title = models.Char ...
- 中介模型,cbv视图,和查询优化
中介模型: 处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的ManyToManyField 就可以了.但是,有时你可能需要关联数据到两个模型之间的关系上. 例如,有这 ...
- Django-model进阶(中介模型,查询优化,extra,整体插入)
QuerySet 可切片 使用Python 的切片语法来限制查询集记录的数目 .它等同于SQL 的LIMIT 和OFFSET 子句. ? 1 >>> Entry.objects.al ...
随机推荐
- EM5-PE2B
1. vocabulary once adv. 一次,曾经 They cocktailed once every week. He once lived in shanghai. twice adv ...
- 初识PowerShell
一.简介 Windows PowerShell 是微软公司为Windows环境所开发的壳程序(shell)及脚本语言技术,采用的是命令行界面.这项全新的技术提供了丰富的控制与自动化的系统管理能力.之前 ...
- ORACLE / PLSQL 插入或更新数据的几种方式
第一种,直接用values 插入 ---日期需要用TO_DATE操作 INSERT INTO EMP (EMPNO,ENAME ,JOB,MGR, HIREDATE , SAL ,COMM, DEPT ...
- ECMall中Widgets模式的布局引擎
自己做过框架的人,可能都会思考一个问题,模板引擎需要什么特性? Widgets模式,很多系统中都有出现,但对于纯开发人员,不管前端或后台人员来说,都觉得稍微麻烦了一点.因为他将界面硬生生的拆分出了很多 ...
- 【Mac + Android】之Android Studio 环境搭建,AVD模拟器运行(包括:命令行运行AVD,并且Genymotion模拟器插件配置运行)
目录: 前提.Mac环境下手动配置Android SDK 一. Android Studio下载及配置 二.AVD模拟器配置运行 扩展:命令行运行AVD模拟器 三.在Android Studio 中配 ...
- python入门(四):标准输出和文件读写
Python输出 1.表达式语句 str(): 函数返回一个用户易读的表达形式,可以使用 str.format() 函数来格式化输出值. repr(): 产生一个解释器易读的表达形式. 2.print ...
- Database Designer
DBDesigner http://fabforce.net/dbdesigner4/index.php DB Designer Fork http://sourceforge.net/project ...
- 简单的php基于curl的反向代理程序
起因: 经理:需要实现一个反向代理? 我: 简单,nginx分分钟配置好. 经理:嗯?没有nginx? 我: nodejs也行啊,网上有例子分分钟搞定. 经理:嗯?只有虚拟主机,只能上传php程序? ...
- linux连接mysql命令
连接MYSQL: 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1:连接到本机上的MYSQL 找到mysql的安装目录,一般可以直接键入命令mysql -uroot -p,回车后提 ...
- elasticsearch.net search入门使用指南中文版
原文:http://edu.dmeiyang.com/book/nestusing.html elasticsearch.net为什么会有两个客户端? Elasticsearch.Net是一个非常底层 ...