Django关联模型反向查询名定义及冲突报错原因求解
Django 反向查询相关命名规则
- 反向访问属性名(
related_name):当模型A定义ForeignKey指向模型B时,Django会自动在B上创建用于反向调取关联实例的属性,默认命名规则为A的小写类名_set。比如本场景中Category定义了指向Product的外键,默认反向属性名就是category_set。 - 反向查询过滤名(
related_query_name):用于ORM跨表过滤时的字段标识,默认规则为:如果自定义了related_name就直接取related_name的值,否则取related_name默认值去掉_set后缀,也就是A的小写类名。该名称会和模型自身的字段名共享查询命名空间,重名就会触发冲突。
本次冲突的具体成因
你之前的判断只考虑了related_name的category_set不会和Product.category重名,但忽略了related_query_name的生成规则:
Product模型本身已经定义了名为category的外键字段。Category的featured_product外键没有指定任何关联命名参数,它的默认related_query_name就是category,刚好和Product的自有字段名完全一致。- 此时执行类似
Product.objects.filter(category=xxx)的查询时,Django无法判断category指代的是Product自身的字段,还是featured_product对应的反向查询关系,因此抛出E303冲突错误。
如果不想禁用反向关系,除了设置related_name="+"之外,也可以手动指定related_name或者related_query_name避免冲突,比如给featured_product字段添加参数related_name="featured_categories"即可。
内容的提问来源于stack exchange,提问作者Max Be
相关产品推荐
相关产品推荐

