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 ...
随机推荐
- jsp的页面包含——静态包含、动态包含
一.静态包含:包含的文件可以是jsp文件.html文件.文本文件或者一段java代码.<%@ include file="要包含的文件路径"%> 实质是先将所包含的文件 ...
- 李洪强iOS经典面试题31-解释垃圾回收的原理
李洪强iOS经典面试题31-解释垃圾回收的原理 问题 我们知道,Android 手机通常使用 Java 来开发,而 Java 是使用垃圾回收这种内存管理方式. 那么,ARC 和垃圾回收对比,有什么优点 ...
- Spring事务的隔离级别
1. ISOLATION_DEFAULT: 这是一个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别. 另外四个与 JDBC的隔离级别相对应: ...
- Entity简单使用
urlEntity: //定义 package com.example.cc.ecustapp.Model; /** * Created by weijiawang on 2016/3/8. */pu ...
- Android 开发 -------- 自己定义View 画 五子棋
自己定义View 实现 五子棋 配图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbG92ZV9KYXZjX3lvdQ==/font/5a6L5L2T ...
- 在Linux下搭建git服务器
http://www.cnblogs.com/dee0912/p/5815267.html 步骤很详细,很受用
- TPM--Trusted Platform Module
trouSerS是IBM的一帮牛人搞的TSS软件栈,提供了与TPM交互的API,从而可以让我们方便地编写应用程序. 地址:https://sourceforge.net/projects/trouse ...
- php ocket通信机制
php 实例说明 socket通信机制 一,socket是什么 什么是socket 所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通 ...
- 利用多态,实现一般处理程序(ashx)中的AOP(切面编程)
本文是对工作中的项目进行代码优化(完善登陆验证的AOP切面编程)时,所遇到的各种解决方案思考过程. 项目背景:由ashx+nvelocity构建的简单B/S问卷系统,现需要优化登录验证环节(时隔若干个 ...
- Tomcat nginx log日志按天分割切割
利用 Linux 自带的 logrotate 工具来实现按天切割日志.下方已 centos 7 系统为例来实践讲解. 原理 Logrotate是基于CRON来运行的,其脚本是/etc/cron.dai ...