Django ORM之多对多三种创建方式

Django ORM多对多的三种模式

1. 使用默认的ManyToManyField创建第三张表、

  • 1. 优势
    • 可以使用ORM提供的快捷方法
      • add()
      • clear()
      • set()
      • remove()
      •  all()
  • 2. 劣势:
    • 不能扩展第三张表

 

from django.db import models

# Create your models here.


class Book(models.Model):
    title = models.CharField(max_length=32)

    def __str__(self):
        return self.title


class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="作者姓名")
    books = models.ManyToManyField(to='Book')

    def __str__(self):
        return self.name
app01/models.py
#!/usr/bin/env python
# -*- coding:utf8 -*-

import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "manytomany_test.settings")
    import django
    django.setup()

    from app01 import models

    author_obj = models.Author.objects.get(id=1)
    ret = author_obj.books.all()
    print(ret)

    # from app02 import models
    #
    # author_obj = models.Author.objects.get(id=1)
    # ret = author_obj.author2book_set.all().values_list("book__title")
    # print(ret)

    # from app03 import models
    # 
    # author_obj = models.Author.objects.get(id=1)
    # ret = author_obj.books.all()
    # print(ret)
    # 删除第一个作者关联的所有书籍,可以直接操作第三张关系表
    # models.Author2Book.objects.filter(author=author_obj).delete()
orm_test

2. 自己创建第三张关系表

 

  • 1. 优势:
    • 可以自己扩展第三章关系表的字段(婚恋网站的男女用户的约会记录)
  • 2. 劣势:
    • 不能使用ORM提供的快捷方法(查询麻烦,需要跨三张表)

 

from django.db import models

# Create your models here.


class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name="书名")

    def __str__(self):
        return self.title


class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="作者姓名")

    def __str__(self):
        return self.name


# 自己创建多对多的第三张表
class Author2Book(models.Model):
    book = models.ForeignKey(to='Book')
    author = models.ForeignKey(to='Author')

    class Meta:
        unique_together = (('book', 'author'), )
app02/models.py
#!/usr/bin/env python
# -*- coding:utf8 -*-

import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "manytomany_test.settings")
    import django
    django.setup()

    # from app01 import models
    # 
    # author_obj = models.Author.objects.get(id=1)
    # ret = author_obj.books.all()
    # print(ret)

    from app02 import models

    author_obj = models.Author.objects.get(id=1)
    ret = author_obj.author2book_set.all().values_list("book__title")  # 先是外键反向查询, 在是外键正向查询
    print(ret)

    # from app03 import models
    #
    # author_obj = models.Author.objects.get(id=1)
    # ret = author_obj.books.all()
    # print(ret)
    # 删除第一个作者关联的所有书籍,可以直接操作第三张关系表
    # models.Author2Book.objects.filter(author=author_obj).delete()
orm_test

3.自己创建第三张表,在ManyToManyField中通过through和through_fields指定表名和字段

  • 1. 优势:
    • 可以使用ORM提供的部分快捷方法
      • all()
    • 可以扩展第三张关系表的字段
from django.db import models

# Create your models here.


class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name="书名")

    def __str__(self):
        return self.title


class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="作者姓名")
    books = models.ManyToManyField(
        to='Book',
        through='Author2Book',
        through_fields=('author', 'book')  # 这里是有顺序的,在那个表种写关联,那个字段就要写的前面
    )

    def __str__(self):
        return self.name


# 自己创建多对多的第三张表
class Author2Book(models.Model):
    book = models.ForeignKey(to='Book')
    author = models.ForeignKey(to='Author')

    class Meta:
        unique_together = (('book', 'author'),)
app03/models.py
#!/usr/bin/env python
# -*- coding:utf8 -*-

import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "manytomany_test.settings")
    import django
    django.setup()

    # from app01 import models
    #
    # author_obj = models.Author.objects.get(id=1)
    # ret = author_obj.books.all()
    # print(ret)

    # from app02 import models
    # 
    # author_obj = models.Author.objects.get(id=1)
    # ret = author_obj.author2book_set.all().values_list("book__title")  # 先是外键反向查询, 在是外键正向查询
    # print(ret)

    from app03 import models

    author_obj = models.Author.objects.get(id=1)
    ret = author_obj.books.all()  # 只可使用多对多关系种的all()方法
    print(ret)
    
    # 删除第一个作者关联的所有书籍,可以直接操作第三张关系表
    models.Author2Book.objects.filter(author=author_obj).delete()
orm_test

 

posted @ 2018-08-13 17:29  Mr.GLH  阅读(1530)  评论(0编辑  收藏  举报
Top↑