You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django报fields.E304 Reverse accessor反向访问器冲突问题求助

Django E304反向访问器冲突报错排查

问题背景

首先说明,本问题并非重复提问,我已查阅过同类问题的现有解决方案,但均无法解决我遇到的问题,恳请协助排查。
我在应用中定义了如下模型代码:

class Company(models.Model):
    owner = models.ForeignKey(User, verbose_name="User", on_delete=models.CASCADE, default=None, null=True, blank=True)
    name = models.CharField(max_length=128, blank=True, null=True, default=None)
    created = models.DateTimeField(auto_now_add=True, auto_now=False, null=True, blank=True)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True, null=True, blank=True)


def create_folder(**kwargs):
    instance = kwargs.get('instance')
    print(instance.id)
    os.mkdir(f"media/company_{instance.id}")


def delete_folder(**kwargs):
    instance = kwargs.get('instance')
    print(instance.id)
    full_patch_folder = f"media/company_{instance.id}"
    if os.path.isdir(full_patch_folder):
        shutil.rmtree(full_patch_folder)


post_save.connect(create_folder, sender=Company)
post_delete.connect(delete_folder, sender=Company)


class Folder(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=128, blank=True, null=True, default=None)
    unique_folder_name = models.CharField(max_length=128, blank=True, null=True, default=None)
    full_path = models.CharField(max_length=256, blank=True, null=True, default=None)
    parent_folder = models.IntegerField(verbose_name="Parent Folder", blank=True, null=True, default=0)
    company = models.ForeignKey(Company, verbose_name="Company", on_delete=models.CASCADE, default=None)
    share = models.BooleanField(verbose_name="Share folder", null=True, default=False)
    created = models.DateTimeField(auto_now_add=True, auto_now=False, null=True, blank=True)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True, null=True, blank=True)

    def __str__(self):
        return "(id.%s) - %s - %s - %s - %s" % (self.id, self.name, self.unique_folder_name,  self.share, self.company)

运行代码时收到如下报错:

apps.Company.owner: (fields.E304) Reverse accessor for 'Company.owner' clashes with reverse accessor for 'Company.owner'.
    HINT: Add or change a related_name argument to the definition for 'Company.owner' or 'Company.owner'.
main.Company.owner: (fields.E304) Reverse accessor for 'Company.owner' clashes with reverse accessor for 'Company.owner'.
    HINT: Add or change a related_name argument to the definition for 'Company.owner' or 'Company.owner'.

报错根因

报错里已经明确标出了冲突来源:apps.Company.owner和main.Company.owner,说明你的项目里在apps和main两个不同应用下,各定义了一个名为Company的模型。
Django的外键字段会默认在关联的目标模型上生成反向访问属性,命名规则为<来源模型名小写>_set,两个不同app下的Company模型都有指向User模型的owner外键,默认生成的反向访问属性名完全一致,就会触发命名冲突,抛出E304错误。
你贴出的单份模型代码本身没有语法问题,冲突来自你没注意到的另一个app下的同名Company模型。

修复方案

选任意一种方案处理即可:

  • 清理重复模型
    分别检查apps/models.py和main/models.py两个文件,删除其中一个多余的Company模型定义,保证整个项目中只有一个Company模型,即可彻底消除冲突。
  • 给外键设置唯一的related_name
    如果你确实需要在两个app下保留各自的Company模型,就给两个模型的owner外键分别设置全局唯一的反向访问器名称,避免重名,示例修改如下:
    1. apps应用下的Company模型owner字段添加related_name:
    owner = models.ForeignKey(
        User, 
        verbose_name="User", 
        on_delete=models.CASCADE, 
        default=None, 
        null=True, 
        blank=True,
        related_name="apps_owned_company"
    )
    
    1. main应用下的Company模型owner字段添加related_name:
    owner = models.ForeignKey(
        User, 
        verbose_name="User", 
        on_delete=models.CASCADE, 
        default=None, 
        null=True, 
        blank=True,
        related_name="main_owned_company"
    )
    

修改完成后,依次执行python manage.py makemigrations、python manage.py migrate即可正常启动服务。


内容的提问来源于stack exchange,提问作者juicy1221

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:12:16