【问题标题】:Django Foreign Key not recognising primary key in relationDjango外键无法识别相关的主键
【发布时间】:2016-08-04 13:32:38
【问题描述】:

我有两个模型,ArticleArticlePostArticlePostArticle 引用为外键,并且在 Article 的单独应用程序中:

====app1/models.py:======
class Article(models.Model):

     name = models.CharField(max_length=200, primary_key=True)

====app2/models.py======
class ArticlePost(models.Model):

    article = models.ForeignKey(Article, null=False, db_index=True)
    created_at = models.DateTimeField(auto_now_add=True)
    comment = models.TextField(blank=True)

我已经运行了 python manage makemigrations,它给出了以下内容:

operations = [
migrations.CreateModel(
    name='ArticlePost',
    fields=[
        ('id', models.AutoField(auto_created=True, verbose_name='ID', serialize=False, primary_key=True)),
        ('created_at', models.DateTimeField(auto_now_add=True)),
        ('comment', models.TextField(blank=True)),
        ('article', models.ForeignKey(to='app2.Article')),
    ],
),
]

但是,当我运行 python manage migrate 时,我得到:

django.db.utils.ProgrammingError: there is no unique constraint matching given keys for referenced table "article"

奇怪的是我在app1 中有另一个模型,它也引用了具有完美工作的外键的文章。但是在这种情况下,Django 似乎不知道哪个字段是Article 的主键。唯一的区别是ArticlePostArticle 在不同的应用程序中。我正在运行 Django 1.10。有谁知道是什么原因造成的以及如何解决?

或者,如果这只是一个关键问题,也许解决方案是删除文章上的 primary_key 并改用 Django 默认的 id。在这种情况下,如何在保持其他模型对 app1 内文章的外键引用的同时最好地做到这一点?

【问题讨论】:

  • 这不能回答您的问题,但您可以在模型字段中删除 null=False。默认情况下,null=False。如果您将其设置为True,则只需添加null 值。

标签: python django django-models django-postgresql


【解决方案1】:

好的,所以您尝试做的是绝对正确的。但这里的问题在于 Django。

当您将name 设置为primary_key 时,根据官方文档-> https://docs.djangoproject.com/ja/1.9/ref/models/fields/#django.db.models.Field.unique

primary_key=True 意味着 null=False 和 unique=True。

所以从技术上讲,您的 Article 模型中确实有一个独特的字段,但是在浏览了 Stackoverflow 上的其他几篇帖子之后,

将此作为参考(也通过 cmets)-> Primary key and unique key in django

primary_key=true 似乎有一些问题。 似乎django只将其视为主键而不是unique

因此,当您将 primary_key=true 用于 name 时,Django 不会创建它拥有唯一的对象自动递增 ID。因此,现在您在模型 Article 中没有任何唯一的对象 ID,因此您会收到错误。

因此,只需删除 primary_key=true 并让 Django 使用其自己的自动递增唯一 ID,您就不会出现该错误。

【讨论】:

  • 感谢 Ankush,很高兴知道发生了什么。当我尝试时,我得到You are trying to add a non-nullable field 'id' to Article without a default; we can't do that (the database needs something to populate existing rows)。该默认值应该是什么?似乎 Django 没有意识到它需要用新的 id 自动填充现有记录。其次,假设我可以给出一个值,现有模型的外键为Article 会发生什么?他们会得到维护吗?
  • 是的,你说得对,Django 没有意识到它需要自动填充,因为它只在将新对象添加到该模型时添加唯一的 id。所以现在,没有添加新的,因此它不会填充已经存在的。我想您必须使用python manage.py shell 自己添加它们,然后运行一个简单的循环来执行此操作。否则,如果您可以备份数据,请删除当前数据,然后重新添加该数据。这样,它将为新创建的 ID 创建 ID。还要在添加新数据之前删除所有迁移并进行新的迁移。
  • 我不确定你的第二个问题,但我觉得如果 Django 不允许你首先保留该外键,那么最初不会保存外键,对吧?所以维护的场景不会出现。是吗?
  • 我认为您已经在数据库中有数据,现在您正在尝试在表上添加关系,因此当您将其声明为主键时,它可能有一些数据包含空值或者可能是该列没有所有独特的价值。尽管如此,如果您尝试执行unique=True它会给您错误。
【解决方案2】:

@mohevi,请检查您是否使用 MongoDb 作为数据库,因为 mongodb 不支持外键功能。这些通常在 RDBMS 中得到支持,如 postgresql、MySQL 等

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 2016-08-23
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 2020-10-09
    相关资源
    最近更新 更多