Python - Django - ORM 多对多操作

models.py:

from django.db import models


# 出版社
class Publisher(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64, null=False, unique=True)

    def __str__(self):
        return "<Publisher object: {}>".format(self.name)


# 书籍
class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=64, null=False, unique=True)
    publisher = models.ForeignKey(to="Publisher")

    def __str__(self):
        return "<Book object: {}>".format(self.title)


# 作者
class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=16, null=False, unique=True)
    book = models.ManyToManyField(to="Book")  # 多对多关联 Book 表,ORM 会自动生成第 3 张表

    def __str__(self):
        return "<Author object: {}>".format(self.name)

book 表:

author 表:

author 和 book 关联的第三张表,author_book 表:

publisher 表:

 

多对多的查询:

orm.py:

import os

if __name__ == '__main__':
    # 加载 Django 项目的配置信息
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
    # 导入 Django,并启动 Django 项目
    import django
    django.setup()

    from app01 import models

    author_obj = models.Author.objects.get(id=2)  # 获取 id 为 2 的作者
    ret = author_obj.book.all()  # 查询 id 为 2 的作者写的所有书
    print(ret)

运行结果:

 

create():

创建一个新的对象,保存对象,并将它添加到关联对象集之中,返回新创建的对象。

orm.py:

import os

if __name__ == '__main__':
    # 加载 Django 项目的配置信息
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
    # 导入 Django,并启动 Django 项目
    import django
    django.setup()

    from app01 import models

    author_obj = models.Author.objects.get(id=1)  # 获取 id 为 1 的作者
    author_obj.book.create(title="《PHP》", publisher_id=2)  # 通过该作者创建一本书

运行结果:

 

add():

把指定的 model 对象添加到关联对象集中

orm.py:

import os

if __name__ == '__main__':
    # 加载 Django 项目的配置信息
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
    # 导入 Django,并启动 Django 项目
    import django
    django.setup()

    from app01 import models

    # 把 id 为 2 的书添加给 id 为 4 的作者
    author_obj = models.Author.objects.get(id=4)
    book_obj = models.Book.objects.get(id=2)
    author_obj.book.add(book_obj)
    
    # 也可以直接使用 id 添加
    # author_obj.book.add(2)

运行结果:

添加多个

orm.py:

import os

if __name__ == '__main__':
    # 加载 Django 项目的配置信息
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
    # 导入 Django,并启动 Django 项目
    import django
    django.setup()

    from app01 import models

    # 添加多个,把 id 大于 4 的书添加给 id 为 3 的作者
    author_obj = models.Author.objects.get(id=3)
    book_objs = models.Book.objects.filter(id__gt=4)
    author_obj.book.add(*book_objs)   # 要用 * 把列表打散再传进去

运行结果:

 

remove():

从关联对象集中移除执行的 model 对象。

orm.py:

import os

if __name__ == '__main__':
    # 加载 Django 项目的配置信息
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
    # 导入 Django,并启动 Django 项目
    import django
    django.setup()

    from app01 import models

    author_obj = models.Author.objects.get(id=3)
    book_obj = models.Book.objects.get(title="《PHP》")
    author_obj.book.remove(book_obj)  # 删除与 title 字段为 《PHP》 的关联
    author_obj.book.remove(5)  # 直接删除

运行结果:

原先 id 为 3 的作者关联的两本书籍本删除了

 

clear():

从关联对象集中清空一切对象。

orm.py:

import os

if __name__ == '__main__':
    # 加载 Django 项目的配置信息
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
    # 导入 Django,并启动 Django 项目
    import django
    django.setup()

    from app01 import models

    # 把 id 为 4 的作者的书籍全清空
    author_obj = models.Author.objects.get(id=4)
    author_obj.book.clear()

运行结果:

author_id=4 的内容全被清空了

 

set():

更新 model 对象的关联对象。

orm.py:

import os

if __name__ == '__main__':
    # 加载 Django 项目的配置信息
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
    # 导入 Django,并启动 Django 项目
    import django
    django.setup()

    from app01 import models

    # 给 id 为 4 的作者添加 id 为 2、3 的两本书
    author_obj = models.Author.objects.get(id=4)
    author_obj.book.set([2, 3])

运行结果:

 

外键补充:

外键中的 clear() 和 remove() 方法只能在 null=True 时用

models.py 中的 Book 类:

# 书籍
class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=64, null=False, unique=True)
    publisher = models.ForeignKey(to="Publisher", null=True)  # 把 null 设置为 True

    def __str__(self):
        return "<Book object: {}>".format(self.title)

orm.py:

import os

if __name__ == '__main__':
    # 加载 Django 项目的配置信息
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
    # 导入 Django,并启动 Django 项目
    import django
    django.setup()

    from app01 import models

    # 清空 id 为 2 的出版社中的书籍
    publisher_obj = models.Publisher.objects.get(id=2)
    publisher_obj.book_set.clear()

运行结果:

publisher_id 为 2 全变为 0

posted @ 2019-08-04 19:25  Sch01aR#  阅读(788)  评论(0编辑  收藏  举报