如何使Django中related_name生成的反向引用在User类中直接可见?
我的开发环境
- IDE: VSCode
- VSCode扩展
- Python
- Pylance
- Ruff
- Python Type Hint
- isort
- djLint
- Django
- Black Formatter
我的问题
我正在使用Django开发一个测验提交网站。
我为测验和用户创建了如下的models.py文件:
class User(AbstractUser): pass class Quiz(models.Model): title = models.CharField(max_length=50) content = models.TextField() user = models.ForeignKey( User, on_delete=models.CASCADE, related_name="posted_quizzes" ) correct_answer = models.CharField(max_length=50)
上述代码借助Django的related_name反向查询功能,为User类添加了posted_quizzes属性。这是个实用功能,但只看User类时没法直观看到这个属性,明明它属于User类。我经常忘这个属性能通过related_name访问,甚至会重复定义新方法。
有没有办法让通过related_name添加的属性能直接在User类中被看到?
我已尝试的方法
我尝试直接添加一个未实现的属性,代码如下:
class User(AbstractUser): @property def posted_quizzes(self): """ defined by related_name of Quiz model posts the user posted """ pass class Quiz(models.Model): title = models.CharField(max_length=50) content = models.TextField() user = models.ForeignKey( User, on_delete=models.CASCADE, related_name="posted_quizzes" ) correct_answer = models.CharField(max_length=50)
这种方法的优点是不会改变迁移,但代码冗余度较高。
解决方案
这里有几种更优雅的方式解决这个问题:
- 类型注解标注反向属性
直接在User类中用类型注解声明反向属性,不需要实现具体逻辑,既不影响迁移,又能让IDE和读代码的人直观看到:
from django.db.models import QuerySet from django.contrib.auth.models import AbstractUser class User(AbstractUser): # 标注反向查询属性的类型,IDE会自动识别并提供提示 posted_quizzes: QuerySet['Quiz'] class Quiz(models.Model): title = models.CharField(max_length=50) content = models.TextField() user = models.ForeignKey( User, on_delete=models.CASCADE, related_name="posted_quizzes" ) correct_answer = models.CharField(max_length=50)
- 在类文档中明确说明反向属性
在User类的文档字符串里统一列出所有反向关联属性,让阅读代码时一眼就能看到:
class User(AbstractUser): """ 用户模型 反向关联属性说明: - posted_quizzes: 用户发布的所有测验,关联自Quiz模型user字段的related_name """ pass
- 用django-stubs增强类型支持
如果你常用类型注解,安装django-stubs库,它能自动识别Django的反向关联属性,不需要手动标注就能让IDE正确提示。安装命令:
pip install django-stubs
配置Pylance启用类型检查后,就能自动感知posted_quizzes这类反向属性。
另外注意你之前的代码里Quiz(models.model)是拼写错误,应该是Quiz(models.Model),这个要修正,否则会触发运行错误。
内容的提问来源于stack exchange,提问作者Kitamado
相关产品推荐
相关产品推荐

