Django Composite 主键与外键的最佳解决方案

问题描述 投票:0回答:2

我想在 Django SQLite DB(ER 图)中满足这种关系,我尝试使用我见过的建议的

unique_together
models.UniqueConstraint
解决方案。

myapp/models.py

class User(models.Model):
    user_id = models.AutoField(primary_key=True, null=False)

class Article(models.Model):
    article_id = models.AutoField(primary_key=True)

class ArticleEditor(models.Model):
        class Meta:
        # RECOMMENDED
        models.UniqueConstraint(fields=['article_id', 'editor_id'], name="article_editor_id",)
        # DEPRECATED
        unique_together = (('article_id', 'editor_id'),)

    article_id = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
    )
    editor_id = models.ForeignKey(
        User,
        on_delete=models.PROTECT,
    )

在这两种情况下,当我尝试通过 python 控制台保存 ArticleEdiotor 对象时,我收到此错误:

>>> from myapp.models import User, Article, ArticleEditor
>>> a = Article.objects.get(article_id=2)
>>> u = User.objects.get(user_id=1)
>>> ae = ArticleEditor(a.article_id, u.user_id)
>>> ae.save()
Traceback (most recent call last):
...
django.db.utils.OperationalError: no such table: myapp_articleeditor

但是,我检查了用于迁移的

sqlmigrate
命令,它确实
CREATE TABLE "myapp_articleeditor"
;但它仍然会产生我不想要的
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT
,因为我希望我的复合键 (
article_editor_id
) 成为主键。我该如何实现这一目标?

这实际上是建立具有中间表的多对多关系的最佳方法,如图所示,还是有更好的解决方案?

python django foreign-keys many-to-many composite-primary-key
2个回答
2
投票

Django 不支持多列主键,建议使用唯一的解决方法,但您仍然会有一列充当真实 id

很长一段时间没有关于这个主题的工作Wiki文章django-compositepks


2
投票

编辑:截至 2024 年 7 月 29 日,添加复合主键的工作仍在进行中。我在下面提到的原始拉取请求似乎已经停滞,开发已转移到基于原始拉取请求于 2024 年 4 月启动的新拉取请求。据我所知,添加复合主键/复合外键的所有工作现在都由这个较新的拉取请求处理。


与 2020 年当前接受的答案相比,截至 2023 年 9 月,似乎正在开展工作以最终实现复合主键/外键。如果我正确理解了 PR 的讨论,那么他们已经可以使用复合主键,但在实际合并更改之前还需要使其与外键一起使用。 有关详细信息,请参阅此 PR:

https://github.com/django/django/pull/17279

© www.soinside.com 2019 - 2024. All rights reserved.