ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多对多关联与中介模型

2021-06-26 17:35:13  阅读:173  来源: 互联网

标签:models max 模型 中介 关联 class book nid id


目录

多对多关联与中介模型

一 多对多关联的三种方式

# 多对多关联关系的建立有三种方式。

1 方式一:自行创建第三张表

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()

# 自己创建第三张表,分别通过外键关联书和作者
class AuthorToBook(models.Model):
    nid = models.AutoField(primary_key=True)
    # 只需要在中间表建立外键关系即可,此表对book和author表不堵车‘一对多’关系中多的一方
    book_id = models.ForeignKey(to=Book, to_field='nid', on_delete=models.CASCADE)
    author_id = models.ForeignKey(to=Author, to_field='nid', on_delete=models.CASCADE)
    date=models.DecimalField()
    class Meta:
        unique_together = ("author", "book")

2 方式二:通过ManyToManyField自动创建第三张表

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    
# 通过ORM自带的ManyToManyField自动创建第三张表
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()
    # 通过ORM自带的ManyToManyField自动创建第三张表
    authors=models.ManyToManyField(to='Author')
    def __str__(self):
        return self.name

3 方式三:使用中介模型(自定义中间表)

# 设置ManyTomanyField并指定自行创建的第三张表
class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name="书名")

# 自己创建第三张表,并通过ManyToManyField指定关联
class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="作者姓名")
    books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book"))
    # through_fields接受一个2元组 ('field1', 'field2'):s
    # 其中field1是定义ManyToManyField的模型外键的名(author),field2是关联目标模型(book)的外键名。

class Author2Book(models.Model):
    author = models.ForeignKey(to="Author")  # 默认的关联字段是id
    book = models.ForeignKey(to="Book")

    class Meta:
        unique_together = ("author", "book")

二 中介模型

1 多对多关系中,第三张表的建立
	-默认使用ManyToMany,自动创建
    -使用中介模型
    	-既手动创建第三张表,又可以使用方便的查询
    -完全自己写第三张表
    
# 使用中介模型

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail', to_field='nid', unique=True, on_delete=models.CASCADE)


class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)


class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()

    publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE)
    # 当前在哪个表中,元组中的第一个参数就是 表明_id
    authors=models.ManyToManyField(to='Author',through='AuthorToBook',through_fields=('book_id','author_id'))
    def __str__(self):
        return self.name


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

class AuthorToBook(models.Model):
    nid = models.AutoField(primary_key=True)
    book_id = models.ForeignKey(to=Book, to_field='nid', on_delete=models.CASCADE)
    author_id = models.ForeignKey(to=Author, to_field='nid', on_delete=models.CASCADE)
    date=models.DecimalField()  # 【不能用add ,remove, clear, set等操作的原因,可能会有新的字段加入,导致数据错误】
    
# 使用中介模型后的方法变化:

# 脚本文件s1.py  
import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day76.settings")
    import django
    django.setup()
    from app01 import models
    ## (a)不使用中介模型的测试:
    # 东游记这本书是lqz和egon写的
    # book=models.Book.objects.get(pk=1)
    # # book.authors.add(1,2) # 自己创建第三张表,不做关联,用不了了
    # # 只能手动写
    # models.AuthorToBook.objects.create(book_id_id=1,author_id_id=1)  # 【写book_id_id的原因:book_id是字段对象,建表的时候,自动加了_id】
    # models.AuthorToBook.objects.create(book_id_id=1,author_id_id=2)

    # 东游记这本书所有的作者:原生写法,不方便
    # book = models.Book.objects.get(pk=1)
    # res=models.AuthorToBook.objects.filter(book_id=book)  ### 【另一种写法:book_id_id = book.nid】
    # print(res)

    ## (b)使用了中介模型之后: 
    # book = models.Book.objects.get(pk=1)
    # print(book.authors.all())
    	
    # 东游记这本书是lqz和egon写的 add ,remove, clear, set
    # 但是连表操作,book.authors这些都能用
    book = models.Book.objects.get(pk=1)
    book.authors.add(1,2) # 不能用了

标签:models,max,模型,中介,关联,class,book,nid,id
来源: https://www.cnblogs.com/chaochaofan/p/14932321.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有