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)

publisher 中的内容:

book 表中的内容:

 

正向查询:

基于对象的查询:

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

    book_obj = models.Book.objects.first()  # 获取第一本书籍对象
    ret = book_obj.publisher  # 获取第一本书籍关联的出版社
    print(ret)
    ret_name = book_obj.publisher.name  # 获取第一本书籍关联的出版社的 name 字段的内容
    print(ret_name)

运行结果:

 

用下划线进行跨表查询:

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

    ret = models.Book.objects.filter(id=1).values_list("publisher__name")  # 查询 id 为 1 的出版社的 name 字段 
    print(ret)

运行结果:

 

反向查询:

基于对象的查询:

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

    publisher_obj = models.Publisher.objects.get(id=2)  # 获取 id 为 2 的出版社
    ret_book = publisher_obj.book_set.all()  # 获取所有该出版社的书籍,book_set 中的 book 是 Book 表的表名小写
    ret_titles = ret_book.values_list("title")  # 获取第二个出版社的所有书的书名
    print(ret_titles)

运行结果:

可以在 Book 类中设置 related_name 来进行别名

修改 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", related_name="aaa")

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

related_name 为 aaa,可以把 book_set 替换为 aaa

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

    publisher_obj = models.Publisher.objects.get(id=2)  # 获取 id 为 2 的出版社
    ret_book = publisher_obj.aaa.all()  # 获取所有该出版社的书籍,book_set 替换为 aaa
    ret_titles = ret_book.values_list("title")  # 获取第二个出版社的所有书的书名
    print(ret_titles)

运行结果:

 

用下划线进行跨表查询:

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

    ret = models.Publisher.objects.filter(id=2).values_list("book__title")  # 获取 id 为 2 的出版社的所有书籍
    print(ret)

运行结果:

可以在 Book 类中设置 related_name 来进行别名

修改 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", related_query_name="bbb")

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

related_query_name 为 bbb,可以把 values_list 中的 book_title 替换为 bbb_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

    ret = models.Publisher.objects.filter(id=2).values_list("bbb__title")  # 获取 id 为 2 的出版社的所有书籍
    print(ret)

运行结果:

 

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