django -- 多对多关系的实现
在django中表和表之间的多对多关系有两种实现方案:
方案一:直接使用django自动实现的多对多关系。
方案二:自己写连接表、然而告诉django在实现多对多关系时要使用的连接表。
一、方案一:
model的定义
from django.db import models class Person(models.Model):
name= models.CharField(max_length=16)
birthday=models.DateField()
class Group(models.Model):
name= models.CharField(max_length=16)
members = models.ManyToManyField(Person)
对应的SQL代码:
BEGIN;
--
-- Create model Group
--
CREATE TABLE "polls_group" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" varchar(16) NOT NULL);
--
-- Create model Person
--
CREATE TABLE "polls_person" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" varchar(16) NOT NULL,
"birthday" date NOT NULL);
--
-- Add field members to group
--
CREATE TABLE "polls_group_members" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"group_id" integer NOT NULL REFERENCES "polls_group" ("id"),
"person_id" integer NOT NULL REFERENCES "polls_person" ("id")); CREATE UNIQUE INDEX "polls_group_members_group_id_person_id_ce176f60_uniq"
ON "polls_group_members" ("group_id", "person_id"); CREATE INDEX "polls_group_members_group_id_f4695d83"
ON "polls_group_members" ("group_id"); CREATE INDEX "polls_group_members_person_id_fb30aa04"
ON "polls_group_members" ("person_id"); COMMIT; -- ----------------------------
delimiter //
create procedure sp_a(a int)
BEGIN
insert into t1(x,a) values(100,a);
end //
delimiter ;
二、方案二:
model的定义
from django.db import models class Person(models.Model):
name= models.CharField(max_length=16)
birthday=models.DateField() def __str__(self):
return self.name class Group(models.Model):
name= models.CharField(max_length=16)
members = models.ManyToManyField(Person,through=MemberShip) class MemberShip(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group) date_join=models.DateTimeField()
invite_reason=models.CharField(max_length=100)
对应的SQL代码:
BEGIN;
--
-- Create model Group
--
CREATE TABLE "polls_group" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" varchar(16) NOT NULL);
--
-- Create model MemberShip
--
CREATE TABLE "polls_membership" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"date_join" datetime NOT NULL,
"invite_reason" varchar(100) NOT NULL,
"group_id" integer NOT NULL REFERENCES "polls_group" ("id"));
--
-- Create model Person
--
CREATE TABLE "polls_person" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" varchar(16) NOT NULL,
"birthday" date NOT NULL);
--
-- Add field person to membership
--
ALTER TABLE "polls_membership" RENAME TO "polls_membership__old";
CREATE TABLE "polls_membership" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"date_join" datetime NOT NULL,
"invite_reason" varchar(100) NOT NULL,
"group_id" integer NOT NULL REFERENCES "polls_group" ("id"),
"person_id" integer NOT NULL REFERENCES "polls_person" ("id")); INSERT INTO "polls_membership" ("id", "date_join", "invite_reason", "group_id", "person_id") SELECT "id", "date_join", "invite_reason", "group_id", NULL FROM "polls_membership__old";
DROP TABLE "polls_membership__old";
CREATE INDEX "polls_membership_group_id_19f13d47" ON "polls_membership" ("group_id");
CREATE INDEX "polls_membership_person_id_fa058fab" ON "polls_membership" ("person_id");
--
-- Add field members to group
--
CREATE TABLE "polls_group_members" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"group_id" integer NOT NULL REFERENCES "polls_group" ("id"),
"person_id" integer NOT NULL REFERENCES "polls_person" ("id")); CREATE UNIQUE INDEX "polls_group_members_group_id_person_id_ce176f60_uniq" ON "polls_group_members" ("group_id", "person_id");
CREATE INDEX "polls_group_members_group_id_f4695d83" ON "polls_group_members" ("group_id");
CREATE INDEX "polls_group_members_person_id_fb30aa04" ON "polls_group_members" ("person_id");
COMMIT;
三、由上面的SQL可以看出django来只是定义了memberShip模式对应的表、它自己也并没有放弃自己的那一套:
model 的定义:
from django.db import models class Person(models.Model):
name= models.CharField(max_length=16)
birthday=models.DateField() class Meta():
db_table="person" class Group(models.Model):
name= models.CharField(max_length=16)
members = models.ManyToManyField(Person,through='MemberShip') class Meta():
db_table="group" class MemberShip(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group) date_join=models.DateTimeField()
invite_reason=models.CharField(max_length=100) class Meta():
db_table="membership"
对应的SQL代码:
BEGIN;
--
-- Create model Group
--
CREATE TABLE "group" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" varchar(16) NOT NULL);
--
-- Create model MemberShip
--
CREATE TABLE "membership" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"date_join" datetime NOT NULL,
"invite_reason" varchar(100) NOT NULL,
"group_id" integer NOT NULL REFERENCES "group" ("id"));
--
-- Create model Person
--
CREATE TABLE "person" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" varchar(16) NOT NULL,
"birthday" date NOT NULL);
--
-- Add field person to membership
--
ALTER TABLE "membership" RENAME TO "membership__old";
CREATE TABLE "membership" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"date_join" datetime NOT NULL,
"invite_reason" varchar(100) NOT NULL,
"group_id" integer NOT NULL REFERENCES "group" ("id"),
"person_id" integer NOT NULL REFERENCES "person" ("id")); INSERT INTO "membership" ("id", "date_join", "invite_reason", "group_id", "person_id")
SELECT "id", "date_join", "invite_reason", "group_id", NULL FROM "membership__old"; DROP TABLE "membership__old"; CREATE INDEX "membership_group_id_786fce67" ON "membership" ("group_id");
CREATE INDEX "membership_person_id_8ed25d16" ON "membership" ("person_id");
--
-- Add field members to group
--
ALTER TABLE "group" RENAME TO "group__old";
CREATE TABLE "group" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" varchar(16) NOT NULL); INSERT INTO "group" ("id", "name")
SELECT "id", "name" FROM "group__old"; DROP TABLE "group__old";
COMMIT;
总结:
1、在定义模式时指定数据库中的表名是一个好的习惯、这样django就不会建立一些不需要的表了。
2、对于多对多关系还是自己实现多对多关系比较好、一来可以保存一些额外的有用信息、表名也更加统一。
----
django -- 多对多关系的实现的更多相关文章
- Django多对多关系建立及Form组件
目录 Django多对多关系 1.创建方式一全自动 2.创建方式二纯手撸 3.半自动(推荐使用) forms校验组件 使用forms组件实现注册功能 form常用字段和插件 数据校验 钩子函数 HOO ...
- Django --- 多对多关系创建,forms组件
目录 多对多三种创建方式 1.系统直接创建 2.自己手动创建 3.自己定义加与系统创建 forms组件 1. 如何使用forms组件 2. 使用forms组件校验数据 3. 使用forms组件渲染标签 ...
- Django 多对多 关系
多对多,本意就是多个一对多的关系 定义多对多 ManyToManyField 字段 from django.db import models # 学生类 class Student(models.Mo ...
- django 学习-10 Django多对多关系模型
1.vim blog/models.py class Author(models.Model): name = models.CharField(max_length=30) def unicod ...
- django笔记-模型数据模板呈现过程记录(多对多关系)
首先,推荐一个网址:http://www.tuicool.com/articles/BfqYz2F,因为这里的比我的要有条理,更有利于各位的理解. 以下仅为为个人一次不完整的笔记: 环境:ubuntu ...
- Django 一对多,多对多关系解析
[转]Django 一对多,多对多关系解析 Django 的 ORM 有多种关系:一对一,多对一,多对多. 各自定义的方式为 : 一对一: OneToOneField ...
- django ORM模型表的一对多、多对多关系、万能双下划线查询
一.外键使用 在 MySQL 中,如果使用InnoDB引擎,则支持外键约束.(另一种常用的MyIsam引擎不支持外键) 定义外键的语法为fieldname=models.ForeignKey(to_c ...
- Django 之多对多关系
1. 多对多关系 作者 <--> 书籍 1. 表结构设计 1. SQL版 -- 创建作者表 create table author( id int primary key auto_inc ...
- Linux下开发python django程序(django数据库多对多关系)
1.多对多关系数据访问 models.py设置 from django.db import models # Create your models here. sex_choices=( ('f',' ...
随机推荐
- apache跨域
http://www.cnblogs.com/2050/p/3191744.html http://blog.csdn.net/qq_15283821/article/details/54405805 ...
- C#用openfiledialog文件和savefileDialog打开和保存文件
一 打开文件 Stream myStream = null; OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog ...
- LLVM lli llc
http://zke1ev3n.me/2016/01/18/%E5%9F%BA%E4%BA%8ELLVM%E7%9A%84%E4%BB%A3%E7%A0%81%E6%B7%B7%E6%B7%86/ h ...
- 使用C语言操作InfluxDB
环境: CentOS6.5_x64 InfluxDB版本:1.1.0 InfluxDB官网暂未提供C语言开发库,但github提供的有: https://github.com/influxdata/i ...
- 解决mybatis报错Result Maps collection does not contain value for java.lang.Integer
解决办法:1.检查mybatis的xml配置 2.在某处肯定有配错了的,如"resultMap" -->"resultType" [html] view ...
- minimum-path-sum-动态规划
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...
- C++11新特性之 std::forward(完美转发)(转)
我们也要时刻清醒,有时候右值会转为左值,左值会转为右值. (也许“转换”二字用的不是很准确) 如果我们要避免这种转换呢? 我们需要一种方法能按照参数原来的类型转发到另一个函数中,这才完美,我们称之为完 ...
- cocos2d-js 3.0 屏幕适配方案 分辨率适应
首先介绍一个api和相应的参数: cc.view.setDesignResolutionSize(1024, 768, cc.ResolutionPolicy.FIXED_WIDTH); 这里设置游戏 ...
- SSM:spring+springmvc+mybatis框架中的XML配置文件功能详细解释(转)
原文:https://blog.csdn.net/yijiemamin/article/details/51156189# 这几天一直在整合SSM框架,虽然网上有很多已经整合好的,但是对于里面的配置文 ...
- HttpServletRequest对象(一)
javaweb学习总结(十)——HttpServletRequest对象(一) 一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HT ...