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应用开发实战(视频教学版)》,获出版社和作者授权发布。

相关推荐
LilySesy4 分钟前
ABAP+在select的时候,可以A=B A=C B=C这样子JOIN吗?
数据库·sql·ai·excel·sap·abap
升鲜宝供应链及收银系统源代码服务31 分钟前
升鲜宝生鲜配送供应链管理系统--- 《多语言商品查询优化方案(Redis + 翻译表 + 模糊匹配)》
java·数据库·redis·bootstrap·供应链系统·生鲜配送·生鲜配送源代码
JH307333 分钟前
Redis 中被忽视的“键过期策略”与内存回收机制
数据库·redis·缓存
Microsoft Word33 分钟前
Redis常见面试题
数据库·redis·缓存
bing.shao38 分钟前
mongodb与redis在聊天场景中的选择
数据库·redis·mongodb
dudke39 分钟前
c#实现redis的调用与基础类
数据库·redis·缓存
苦学编程的谢39 分钟前
Redis_7_hash
数据库·redis·哈希算法
许愿OvO41 分钟前
MySQL-索引
数据库·mysql
-指短琴长-41 分钟前
MySQL快速入门——基本查询(上)
android·数据库·mysql
Yeats_Liao1 小时前
时序数据库系列(四):InfluxQL查询语言详解
数据库·后端·sql·时序数据库