为何给Django模型添加related_name会破坏使用_set.all的查询集及模板?
问题原因分析
咱们先理清楚Django反向关联的默认规则和related_name的核心作用:
- 当你在
TestModel里定义ForeignKey关联到其他模型(比如你代码里的example_b对应的模型)时,Django会自动给关联模型的实例生成一个默认反向属性,格式是[关联模型小写]_set——也就是这里的testmodel_set,用来获取所有关联的TestModel实例。 - 但一旦你给这个
ForeignKey设置了related_name(比如你写的related_name='examplesb'),这个自定义名称会完全替换掉默认的testmodel_set属性。也就是说,如果你模板里的demo是example_b对应模型的实例,那原来的demo.testmodel_set.all就找不到对应的属性了,模板渲染时会直接报错,导致HTML页面异常。
快速修复方案
这里有两个简单的解决办法,你可以根据需求选择:
方案1:修改模板代码
把模板中所有用到example_b对应模型实例反向关联的testmodel_set,替换成你设置的related_name也就是examplesb。比如把:
{% for i in demo.testmodel_set.all|... %}
改成:
{% for i in demo.examplesb.all|... %}
方案2:保留默认反向名称(无需修改模板)
如果不想改动模板代码,可以在设置related_name时,在名称末尾加一个+号。这样Django会保留默认的testmodel_set属性,同时新增你自定义的examplesb反向关联。修改后的模型代码如下:
example_b = models.ForeignKey(example_b, related_name='examplesb+')
这样模板里原来的demo.testmodel_set.all依然能正常使用,你也能通过examplesb访问反向关联,一举两得。
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

