【问题标题】:The same name for different models in different Django applications不同Django应用中不同模型的同名
【发布时间】:2021-11-28 11:03:40
【问题描述】:

我在 Django 项目中有应用程序 1 和应用程序 2。我需要每个应用程序都有自己的名为 Task 和 File 的表。每个应用程序中的 File 表将 ForeignKey 引用到自己应用程序中的 Task 表。它看起来像这样:

app1.models

class Task(BasicTask):
    task_id = models.IntegerField(primary_key=True)

class File(BasicFile):
    file_id = models.AutoField(primary_key=True)
    task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='Task_one')

app2.models

class Task(BasicTask):
    task_id = models.IntegerField(primary_key=True)

class File(BasicFile):
    file_id = models.AutoField(primary_key=True)
    task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='Task_two')

ma​​in.models

class BasicTask(models.Model):
    name = models.TextField()
    priority = models.IntegerField()
    status = models.IntegerField(default=0)
    user = models.ForeignKey(
        CustomUser, on_delete=models.CASCADE, null=True, related_name='+')
    
    def __str__(self):
        return f"{self.id}. {self.name}"


class BasicFile(models.Model):
    unique_id = models.TextField()
    status = models.IntegerField(default=0)
    user = models.ForeignKey(
        CustomUser, on_delete=models.CASCADE, null=True, related_name='+')
    content = models.TextField()
    def __str__(self):
        return f"{self.id}. {self.unique_id}"
        

问题是我在进行迁移时遇到以下错误:

ERRORS:
app2.Task.basictask_ptr: (fields.E304) Reverse accessor for 'app2.Task.basictask_ptr' clashes with reverse accessor for 'app1.Task.basictask_ptr'.
        HINT: Add or change a related_name argument to the definition for 'app2.Task.basictask_ptr' or 'app1.Task.basictask_ptr'.
app2.Task.basictask_ptr: (fields.E305) Reverse query name for 'app2.Task.basictask_ptr' clashes with reverse query name for 'app1.Task.basictask_ptr'.
        HINT: Add or change a related_name argument to the definition for 'app2.Task.basictask_ptr' or 'app1.Task.basictask_ptr'.
app1.Task.basictask_ptr: (fields.E304) Reverse accessor for 'app1.Task.basictask_ptr' clashes with reverse accessor for 'app2.Task.basictask_ptr'.
        HINT: Add or change a related_name argument to the definition for 'app1.Task.basictask_ptr' or 'app2.Task.basictask_ptr'.
app1.Task.basictask_ptr: (fields.E305) Reverse query name for 'app1.Task.basictask_ptr' clashes with reverse query name for 'app2.Task.basictask_ptr'.
        HINT: Add or change a related_name argument to the definition for 'app1.Task.basictask_ptr' or 'app2.Task.basictask_ptr'.

您能告诉我如何纠正这些错误吗?

【问题讨论】:

  • 虽然你在不同的应用程序中制作模型但它会保存在单个数据库中(可能是)
  • @sunilghimire 表以应用程序名称的前缀存储在数据库中。例如:app1_task、app2_task等
  • 您可以使用“as”更改导入的名称来修复它。示例:申请 1:from app1.models import MyModel -----申请 2:from app1.models import MyModel as YourModel
  • @EliasPrado 我知道这种可能性,但在这种情况下这不是我所需要的。
  • 您是否尝试过使用多态模型?它可能会帮助您完成您正在尝试做的事情。但是,所有的数据都会放在那里。

标签: python python-3.x django django-models django-orm


【解决方案1】:

因此,为了修复这个错误,有必要这样做:

app1.models

class Task(BasicTask):
    task_id = models.IntegerField(primary_key=True)
    basictask_ptr = models.OneToOneField(BasicTask, on_delete=models.CASCADE, related_name='app1', parent_link=True)

class File(BasicFile):
    file_id = models.AutoField(primary_key=True)
    basicfile_ptr = models.OneToOneField(BasicFile, on_delete=models.CASCADE, related_name='app1', parent_link=True)
    task = models.ForeignKey(Task, on_delete=models.CASCADE)

app2.models

class Task(BasicTask):
    task_id = models.IntegerField(primary_key=True)
    basictask_ptr = models.OneToOneField(BasicTask, on_delete=models.CASCADE, related_name='app2', parent_link=True)

class File(BasicFile):
    file_id = models.AutoField(primary_key=True)
    basicfile_ptr = models.OneToOneField(BasicFile, on_delete=models.CASCADE, related_name='app2', parent_link=True)
    task = models.ForeignKey(Task, on_delete=models.CASCADE)

ma​​in.models

class BasicTask(models.Model):
    name = models.TextField()
    priority = models.IntegerField()
    status = models.IntegerField(default=0)
    user = models.ForeignKey(
        CustomUser, on_delete=models.CASCADE, null=True, related_name='+')
    
    def __str__(self):
        return f"{self.id}. {self.name}"


class BasicFile(models.Model):
    unique_id = models.TextField()
    status = models.IntegerField(default=0)
    user = models.ForeignKey(
        CustomUser, on_delete=models.CASCADE, null=True, related_name='+')
    content = models.TextField()
    def __str__(self):
        return f"{self.id}. {self.unique_id}"
        

【讨论】:

    【解决方案2】:

    Django 向你展示错误并说:

    Add or change a related_name argument to the definition for ...

    所以你需要去models.fields:

    1. app2.Task.basictask_ptr
    2. app1.Task.basictask_ptr

    并将两个模型的 basictask_ptr 字段的 related_name 添加/更改为不同的值。

    更多相关领域是here

    【讨论】:

    • 非常感谢。没有你的帮助,我是做不到的
    猜你喜欢
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    相关资源
    最近更新 更多