在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 -- 多对多关系的实现的更多相关文章

  1. Django多对多关系建立及Form组件

    目录 Django多对多关系 1.创建方式一全自动 2.创建方式二纯手撸 3.半自动(推荐使用) forms校验组件 使用forms组件实现注册功能 form常用字段和插件 数据校验 钩子函数 HOO ...

  2. Django --- 多对多关系创建,forms组件

    目录 多对多三种创建方式 1.系统直接创建 2.自己手动创建 3.自己定义加与系统创建 forms组件 1. 如何使用forms组件 2. 使用forms组件校验数据 3. 使用forms组件渲染标签 ...

  3. Django 多对多 关系

    多对多,本意就是多个一对多的关系 定义多对多 ManyToManyField 字段 from django.db import models # 学生类 class Student(models.Mo ...

  4. django 学习-10 Django多对多关系模型

    1.vim blog/models.py class   Author(models.Model): name = models.CharField(max_length=30) def unicod ...

  5. django笔记-模型数据模板呈现过程记录(多对多关系)

    首先,推荐一个网址:http://www.tuicool.com/articles/BfqYz2F,因为这里的比我的要有条理,更有利于各位的理解. 以下仅为为个人一次不完整的笔记: 环境:ubuntu ...

  6. Django 一对多,多对多关系解析

    [转]Django 一对多,多对多关系解析   Django 的 ORM 有多种关系:一对一,多对一,多对多. 各自定义的方式为 :        一对一: OneToOneField         ...

  7. django ORM模型表的一对多、多对多关系、万能双下划线查询

    一.外键使用 在 MySQL 中,如果使用InnoDB引擎,则支持外键约束.(另一种常用的MyIsam引擎不支持外键) 定义外键的语法为fieldname=models.ForeignKey(to_c ...

  8. Django 之多对多关系

    1. 多对多关系 作者 <--> 书籍 1. 表结构设计 1. SQL版 -- 创建作者表 create table author( id int primary key auto_inc ...

  9. Linux下开发python django程序(django数据库多对多关系)

    1.多对多关系数据访问 models.py设置 from django.db import models # Create your models here. sex_choices=( ('f',' ...

随机推荐

  1. C语言读取 未知长度 的矩阵

    1.确定矩阵行数: 使用每次读取一行函数fgets - row = 0; while(fgets(buf, buflen, fp) != NULL) row++; -   2.确定矩阵列数: - re ...

  2. httpclient Accept-Encoding 乱码

    解决方法 HttpEntity httpEntity = httpResponse.getEntity(); if (httpEntity != null) { if (httpEntity.getC ...

  3. 数据库查询语句报错-ORA-00911: invalid character

    数据库查询语句报错-ORA-00911: invalid character 根据自己经验总结下: 1.都是分号惹的祸,有时候sql语句后面有分好导致这种错误 2.还有一种是从别处copy过来的sql ...

  4. Aerospike系列:2:商业版和社区版的比较

    http://www.aerospike.com/products-services

  5. 【 D3.js 入门系列 — 11 】 入门总结

    D3 新专题首页 一转眼,这个入门系列已经积累了二十二篇文章之多,我想作为 D3.js 这款数据可视化工具的入门来说已经足够了.相信仅仅要看完本系列.以后全然能够在辅以查询的情况下完毕大部分可视化工作 ...

  6. python environ PYTHON_EGG_CACHE

    My first thought was "Wow, that's quite a long way of telling me to 'just quit.'" Not want ...

  7. 妙用Pixel bender执行复杂运算/普通数据运算 传递Vector数组

    最近发现pixel bender有两个特殊点: 1.Input Image4,不单单可以用BitmapData来初始化,也可以用Vector.<Number>初始化. 2.ShaderJo ...

  8. log4j2的xml的配置样例

    log4j2.xml <?xml version="1.0" encoding="UTF-8"?> <Configuration status ...

  9. django之创建第7-2个项目-url配置分离

    1.urls.PY分离 # -*- coding: UTF-8 -*- from django.conf.urls import patterns, include, url # Uncomment ...

  10. 无法启动此程序,因为计算机中丢失 api-ms-win-crt-stdio-l1-1-0.dll 解决

    问题描述 最近用一台Windows Server 2012 R2系统的机器的时候碰到了这个问题. 因为在网上看了很多解决方案,都没有很好的解决.所以记录一下这个问题的解决. 之前使用VS2013编译出 ...