【问题标题】:Django polymorphic models with unique_together具有 unique_together 的 Django 多态模型
【发布时间】:2015-03-01 22:27:30
【问题描述】:

假设我有这些基本模型:

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)

子模型扩展了它:

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

    class Meta:
        unique_together = ['content', 'created_by']

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

django.db.models.fields.FieldDoesNotExist: Like has no field named u'created_by'

【问题讨论】:

  • 您希望Trackable 成为自己的表,通过外键与Like 相关联吗?如果没有,请使用abstract=True,您的unique_together 将按预期工作。如果是这样,您将无法使用 unique_together 强制执行该约束。
  • 我不确定使用 github.com/chrisglass/django_polymorphic 添加它是否能正常工作,因为我没有看到它提到在基本模型中使用 abstract=True。
  • 我看了一眼那个项目,它看起来像是为abstract=False 继承而设计的。在这种情况下,您正在谈论两个不同的表,因此无法以这种方式使用unique_together。注意abstract=True会提供更好的性能并允许唯一约束,所以考虑一下你是否真的需要使用多个表。
  • 感谢@KevinChristopherHenry 我需要使用多态模型,因为它会自动为我转换类型,而且多表允许我查询基本模型

标签: django django-models


【解决方案1】:

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

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

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

  1. 将唯一约束中涉及的所有父模型字段复制到子表中,并表示子字段和从父字段复制的字段的唯一约束,或
  2. 在子视图上创建一个包含父字段和子字段的视图,并在此视图上表达唯一约束。

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

【讨论】:

  • 我相信你 can't copy parent-model fields in inheriting models 所以选项 1 不起作用。
  • 您不能复制父字段,使它们在 Django 的子模型中具有相同的字段名 - 但您可以将它们复制到子模型中的新字段名。我认为您可以设置数据库触发器来保持复制的字段同步。然后如上所述在子模型中的复制字段上表达约束。 (我不是说这漂亮!但这是可能的)
  • 哦,我看到那里的逻辑确实可行。最终,如果 django_polymorphic 设置为与抽象基础模型一起使用,它可以在不将其组合在一起的情况下工作,但似乎没有任何计划支持它。
猜你喜欢
  • 2016-01-12
  • 2017-02-20
  • 2013-05-06
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 2010-12-27
相关资源
最近更新 更多