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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM