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)
运行结果: