具有unique_together的Django多态模型

Jam*_*Lin 7 django django-models

假设我有这些基本模型:

class Trackable(PolymorphicModel):
    uuid = UUIDField(unique=True)
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
Run Code Online (Sandbox Code Playgroud)

儿童模型扩展了它:

class Like(Trackable):
    content = models.ForeignKey(Content, related_name='likes')

    class Meta:
        unique_together = ['content', 'created_by']
Run Code Online (Sandbox Code Playgroud)

当我运行迁移时,它抱怨:

django.db.models.fields.FieldDoesNotExist: Like has no field named u'created_by'
Run Code Online (Sandbox Code Playgroud)

jcd*_*ude 6

这是我处理这个问题的方法。请记住,我使用 PostGres 作为我的数据库,我不知道其他数据库是否也会出现同样的问题(尽管我猜它们会发生)。

唯一的共同约束只能应用于 PostGres 中的单个表或视图。这意味着开箱即用的 Django/Django 多态无法对继承层次结构中 Django 模型的父表和子表中的字段组合表达数据库强制的唯一约束。

如果您确实希望数据库对这些字段强制执行唯一约束,您可以执行以下两件事之一:

  1. 将唯一约束涉及的任何父模型字段复制到子表中,并在子表字段和从父表复制的字段上表达唯一约束,或者
  2. 在子视图上创建一个视图,其中包括来自父视图和子视图的字段,并表达对此视图的唯一约束。

您必须手动执行此操作,或者开发自己的框架来自动插入/更改/删除这些约束。