related_name和related_query_name属性

在Django模型继承中,假如在外键或多对多字段中使用了related_name属性或related_query_name属性,则必须为该字段提供一个独一无二的反向名字和查询名字。但是,这样在抽象基类中一般会引发问题,因为基类中的字段都被子类继承并且保持了同样的值,这其中当然也包括related_name属性和related_query_name属性。

为了解决上述问题,当在抽象基类中(也只能是在抽象基类中)使用related_name属性和related_query_name属性时,部分值需要包含"%(app_label)s"和"%(class)s",具体说明如下:

  • %(class)s:用该字段子类的小写类名替换。
  • %(app_label)s:用小写的、包含子类的应用名替换。每个安装的应用名必须唯一,应用内的每个模型类名也必须唯一,因此替换后的名字也是唯一的。

关于related_name属性或related_query_name属性的使用,示例代码如下:

【代码3-19】

复制代码
01  # --- common app --- #
02  # common/models.py:
03  
04  from django.db import models
05  
06  class Base(models.Model):
07      m2m = models.ManyToManyField(
08          OtherModel,
09          related_name="%(app_label)s_%(class)s_related",
10          related_query_name="%(app_label)s_%(class)ss",
11      )
12  
13      class Meta:
14          abstract = True
15  
16  class ChildA(Base):
17      pass
18  
19  class ChildB(Base):
20      pass
21  
22  # --- another app --- #
23  # another/models.py:
24  
25  from common.models import Base
26  
27  class ChildB(Base):
28      pass

【代码分析】

在第01~20行代码中,定义了第一个Python应用common app,具体内容说明如下:

  • 在第06~14行代码中,定义了一个抽象基类Base:
  1. 在第07~11行代码中,定义了一个多对多属性m2m,并使用了related_name属性和related_query_name属性。
  2. 在第13、14行代码中,在Meta类中添加了属性"abstract=True",表明Base类为抽象 基类。
  • 在第16、17行和第19、20行代码中,定义了两个继承自抽象基类Base的子类ChildA和ChildB,具体内容说明如下:
  1. common.ChildA.m2m字段的反转名是common_childa_related,反转查询名是common_childas。
  2. common.ChildB.m2m字段的反转名是common_childb_related,反转查询名是common_childbs。

在第22~28行代码中,定义了第二个Python应用another app,具体内容说明如下:

  • 在第27、28行代码中,定义了一个继承自抽象基类Base的子类ChildB。其中,another.ChildB.m2m字段的反转名是another_childb_related,反转查询名是another_childbs。

如何使用"%(class)s"和"%(app_label)s"构建关联名字和关联查询名,取决于设计人员。不过,如果在设计时忘了使用"%(class)s"和"%(app_label)s",那么Django会在执行系统检查或运行迁移时抛出错误。如果设计时未指定抽象基类中的related_name属性,那么默认的反转名会是子类名后接"_set"。

本文节选自《Django 5企业级Web应用开发实战(视频教学版)》,获出版社和作者授权发布。

相关推荐
Mr.朱鹏5 小时前
Linux 服务器 LVM 根分区在线动态扩容
linux·服务器·数据库
摇滚侠5 小时前
《SpringBoot 3:入门与应用实战》第 12 章 JDBC 与事务 数据库初始化机制 阅读笔记 36
数据库·spring boot·笔记
qiuhaipeng15 小时前
Claude code 升级后上下文长度变短问题
java·前端·数据库
wxwx_bscxy3225 小时前
基于Python新冠疫情可视化分析系统的设计与实现
java·数据库·spring boot·python·微信小程序·sqlite
剑之所向6 小时前
.NET 官方`System.Threading.Channels`
前端·javascript·数据库
词却7 小时前
数据库基础:DQL 数据查询语言
数据库·oracle
昌原的儿子LEO9 小时前
Linux IO多路复用与SQLite数据库核心知识点总结
linux·数据库·oracle
山岚的运维笔记9 小时前
mysql 专业笔记 -- 第 8 章:使用变量
运维·数据库·笔记·后端·学习·mysql·dba
聚美智数9 小时前
网安查询-备案查询-网络安全查询API接口介绍
网络·数据库·web安全
坐吃山猪10 小时前
【多线程】Semaphore使用
java·数据库·oracle·多线程