zoukankan      html  css  js  c++  java
  • 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、对于多对多关系还是自己实现多对多关系比较好、一来可以保存一些额外的有用信息、表名也更加统一。

    ----

  • 相关阅读:
    软件逆向——软件壳特点总结
    OD调试4----去除nag窗口的几种方法
    OD调试3--获取使用执照
    OD调试2----破解序列号验证程序
    OD调试初步概念——修改窗口标题
    Proj THUDBFuzz Paper Reading: 南京大学软件分析课程2020, 11 Pointer Analysis Context Sensitivity
    Proj THUDBFuzz Paper Reading: 南京大学软件分析课程2020, 08 Pointer Analysis && 09 Pointer Analysis Foundations (I)
    Proj THUDBFuzz Paper Reading: 南京大学软件分析课程2020, 07 Interprocedural Analysis
    Proj THUDBFuzz Paper Reading: 南京大学软件分析课程2020, 05 Data Flow Analysis
    Proj THUDBFuzz Paper Reading: 南京大学软件分析课程2020, 03 Data Flow Analysis
  • 原文地址:https://www.cnblogs.com/JiangLe/p/7921145.html
Copyright © 2011-2022 走看看