Django的Many-to-Many(多对多)模型
Django的Many-to-Many(多对多)模型
日期:2012-05-05 | 来源:未知 | 作者:redice | 人围观 | 1 人鼓掌了!
参考:《DjangoBook2.0》 数据模型高级进阶
经典的例子:一本书有多个作者,一个作者有多本书,典型的多对多关系。
设计模型如下:
- from django.db import models
- class Author(models.Model):
- first_name = models.CharField(max_length=30)
- last_name = models.CharField(max_length=40)
- email = models.EmailField()
- def __unicode__(self):
- return self.name
- class Meta:
- db_table = "author"
- class Book(models.Model):
- title = models.CharField(max_length=200)
- authors = models.ManyToManyField(Author)
- def __unicode__(self):
- return self.title
- class Meta:
- db_table = "book"
python manage.py sqlall books(App名) 看一下Django帮我们生成的数据库表结构:
- CREATE TABLE `author` (
- `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
- `first_name` varchar(30) NOT NULL,
- `last_name` varchar(40) NOT NULL,
- `email` varchar(75) NOT NULL
- )
- ;
- CREATE TABLE `book_authors` (
- `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
- `book_id` integer NOT NULL,
- `author_id` integer NOT NULL,
- UNIQUE (`book_id`, `author_id`)
- )
- ;
- ALTER TABLE `book_authors` ADD CONSTRAINT `author_id_refs_id_22051734` FOREIGN KEY (`author_id`) REFERENCES `author` (`id`);
- CREATE TABLE `book` (
- `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
- `title` varchar(200) NOT NULL
- )
- ;
- ALTER TABLE `book_authors` ADD CONSTRAINT `book_id_refs_id_77516490` FOREIGN KEY (`book_id`) REFERENCES `book` (`id`);
book表中并没有authors字段,其中的book_authors表就是用来存放书和作者多对多映射关系的。
访问多值:
一本书的所有作者:
b = Book.objects.get(id=50)
b.authors.all()
b.authors.filter(first_name='Adam')
反向也可以,一个作者的所有书:
a = Author.objects.get(id=1)
a.book_set.all()
给多对多字段添加值(添加多对多关系):
a = Author.objects.get(id=1)
b = Book.objects.get(id=50)
b.authors.add(a)
从多对多字段中删除值(删除多对多关系):
a = Author.objects.get(id=1)
b = Book.objects.get(id=50)
b.authors.remove(a) 或者 b.authors.filter(id=1).delete()
我想自定义关系表!!!
为什么?
可能的原因:
1)我想添加一些额外的字段;
2)与现有系统集成,关系表已经存在。
定义方法如下:
- # coding: utf-8
- from django.db import models
- class Author(models.Model):
- first_name = models.CharField(max_length=30)
- last_name = models.CharField(max_length=40)
- email = models.EmailField()
- def __unicode__(self):
- return self.name
- class Meta:
- db_table = "author"
- class Book(models.Model):
- title = models.CharField(max_length=200)
- authors = models.ManyToManyField(Author, through='BookAuthor') # 注意多了through参数
- def __unicode__(self):
- return self.title
- class Meta:
- db_table = "book"
- class BookAuthor(models.Model):
- book = models.ForeignKey(Book)
- author = models.ForeignKey(Author)
- created_at = models.DateTimeField(auto_now_add=True) # 我要添加额外的字段
- class Meta:
- db_table = "book_author_relationship" # 我需要用自定义的名称
再看一下此时的数据库表结构:
- BEGIN;
- CREATE TABLE `author` (
- `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
- `first_name` varchar(30) NOT NULL,
- `last_name` varchar(40) NOT NULL,
- `email` varchar(75) NOT NULL
- )
- ;
- CREATE TABLE `book` (
- `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
- `title` varchar(200) NOT NULL
- )
- ;
- CREATE TABLE `book_author_relationship` (
- `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
- `book_id` integer NOT NULL,
- `author_id` integer NOT NULL,
- `created_at` datetime NOT NULL
- )
- ;
- ALTER TABLE `book_author_relationship` ADD CONSTRAINT `author_id_refs_id_6b774382` FOREIGN KEY (`author_id`) REFERENCES `author` (`id`);
- ALTER TABLE `book_author_relationship` ADD CONSTRAINT `book_id_refs_id_7cf7763a` FOREIGN KEY (`book_id`) REFERENCES `book` (`id`);
- CREATE INDEX `book_author_relationship_752eb95b` ON `book_author_relationship` (`book_id`);
- CREATE INDEX `book_author_relationship_337b96ff` ON `book_author_relationship` (`author_id`);
- COMMIT;
爽!
但是这样做也是有不便的地方:多对多字段的add()和remove()方法就不能用了。这里有很好的解释:http://stackoverflow.com/questions/1755591/many-to-many-relationships-with-additional-data-on-the-relationship
https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships
那此时我们如何添加和删除映射关系呢?直接使用BookAuthor模型。
例如:
a = Author.objects.get(id=1)
b = Book.objects.get(id=50)
BookAuthor(book=b, author=a).save()
Django的Many-to-Many(多对多)模型的更多相关文章
- django一对多、多对多模型、自关联的建立
# 原创,转载请留言联系 一对多模型 一对多的关系,例如员工跟部门.一个部门有多个员工.那么在django怎么建立这种表关系呢? 其实就是利用外键,在多的一方,字段指定外键即可.例如员工和部门,员工是 ...
- Django学习笔记之数据库-数据库与模型
MySQL数据库 在网站开发中,数据库是网站的重要组成部分.只有提供数据库,数据才能够动态的展示,而不是在网页中显示一个静态的页面.数据库有很多,比如有SQL Server.Oracle.Postgr ...
- legend3---lavarel多对多模型操作实例
legend3---lavarel多对多模型操作实例 一.总结 一句话总结: 在多对多模型中,增加关系表的数据 需要 弄一个和关系表一对多的模型关系 1.在lavarel关系模型中,课程和标签表是多对 ...
- Python Django框架笔记(五):模型
#前言部分来自Django Book (一) 前言 大多数web应用本质上: 1. 每个页面都是将数据库的数据以HTML格式进行展现. 2. 向用户提供修改数据库数据的方法.(例如:注册.发表评 ...
- Django ORM 一对一,一对多,多对多, 添加,批量插入和查询
模型类 class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_ ...
- Django——7 常用的查询 常用的模型字段类型 Field的常用参数 表关系的实现
Django 常用的查询 常用的查询方法 常用的查询条件 常用字段映射关系 Field常用参数 表关系的实现 查用的查询方法 这是需要用到的数据 from django.http import Htt ...
- django ajax MTV与MVC 多对多创建方式
MTV与MVC MTV模型(django): M:模型层(models.py) T:templates V:views MVC模型: M:模型层(models.py) V:视图层(views.py) ...
- django 中models表的多对一,多对多的理解
django 表的理解 好处:设计的好,会清晰,易于理解和维护,后期开发事半功倍,一目了然. 1. 一对一的表,两表的属性实际上完全可以合并成一个表,共用一个主键即可: 2. 一对多的表,可以设中间关 ...
- Django教程:[33]从数据库生成模型
在使用django做网站的时候,有时候我们的数据库来自一个已有的数据库,如何整合这个数据库呢? django提供了方便的方法来整合已有数据库,下面我们看看具体的方法: 1.先来设置数据库:在网站文件夹 ...
- django “如何”系列8:如何为模型提供初始化数据
当你第一次配置一个app的时候,有时候使用硬编码的数据去预填充你的数据库是非常有用的.这里有几个你可以让django自动创建这些数据的方法:你可以提供固定格式的初始化数据或者提供通过SQL初始化数据. ...
随机推荐
- 非 动态规划---LIS
题目:一个序列有N个数:A[1],A[2],…,A[N],求出最长非降子序列的长度.(见动态规划---LIS) /* 题目:一个序列有N个数:A[1],A[2],…,A[N],求出最长非降子序列的长度 ...
- SSAS中角色(Role)定义需要注意的两个地方
开发过SSAS Cube的朋友应该都知道,我们可以在SSAS中设置若干个角色,把windows账号放入这些角色中来限制不同的windows账号可以看到的数据有哪些,这里有两点需要注意一下. 首先在Cu ...
- FTP小教程
1.下载文件:http://pan.baidu.com/s/1gd3Uo63 2. 右键点击“传送”,就会把本地的文件传送到服务器现在打开的目录
- Ul li 竖排 菜单
Ul li 竖排 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...
- $("label + input") 匹配所有紧接在 prev 元素后的 next 元素
描述: 匹配所有跟在 label 后面的 input 元素 HTML 代码: <form> <label>Name:</label> <input name= ...
- mysql字符串相关
使用MySQL,我们很多时候都会出现需要截取字符串的情况,所以关于字符串的截取的方式有必要记录下去. MySQL截取字符串的函数有: left(str, length):从左边开始截取,length是 ...
- 161025、java提高篇之关键字static
一. static代表着什么 在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个"伪全局"的概念,在Java中static表示"全局"或 ...
- Erlang-基础篇
一.整数运算: 1.Erlang采用不定长的整数来进行整数的算术演算.在Erlang中,整数运算没有误差,因此无需担心运算溢出,也不用为了一个固定字长容纳不下一个大整数而伤脑筋: 二.变量: 1.所有 ...
- linux mmap 内存映射【转】
转自:http://blog.csdn.net/xyyangkun/article/details/7830313 [-] mmap vs readwritelseek mmap vs malloc ...
- jQuery中attr() 和 prop()【转】
Version 1.9.0 开始不建议使用 attr() 来对具有 true 和 false 两个属性的属性进行操作. 具有 true 和 false 两个属性的属性,如 checked, selec ...