2015-03-01 2 views
6

Допустим, у меня есть эти эту базовую модель:Джанго полиморфные модели с unique_together

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' 
+0

Вы хотите, чтобы 'Trackable' был собственной таблицей, связанной с' Like' внешним ключом? Если нет, используйте ['abstract = True'] (https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes), и ваш' unique_together' будет работать должным образом. Если это так, вы не сможете принудить это ограничение к 'unique_together'. –

+0

Я не уверен, что добавление, которое будет работать правильно, с помощью https://github.com/chrisglass/django_polymorphic, поскольку я не вижу в нем упоминания об использовании abstract = True в базовых моделях. –

+0

Я взглянул на этот проект и, похоже, он создан для наследования 'abstract = False'. В этом случае вы говорите о двух разных таблицах, что делает невозможным использование 'unique_together' таким образом. Обратите внимание, что 'abstract = True' обеспечит лучшую производительность и даст уникальное ограничение, поэтому подумайте, действительно ли вам нужно использовать несколько таблиц. –

ответ

2

Вот как я справился с этой проблемой. Имейте в виду, что я использую PostGres как мою базу данных, и я не знаю, возникают ли те же проблемы с другими базами данных (хотя я предполагаю, что они это делают).

Уникальные ограничения могут применяться только к одной таблице или виду в PostGres. Это означает, что Django/Django-polymorphic не может выражать уникальные ограничения, связанные с базами данных, в комбинации полей, которые находятся как в родительской таблице, так и в дочерней таблице моделей Django в иерархии наследования.

Если вы действительно хотите, базы данных применяются уникальные ограничения на этих полях, вы можете сделать один из этих двух вещей:

  1. копию любого родителя-модель поле, которые участвуют в ограничении уникальности в таблицу ребенка, и выразить уникальное ограничение на дочерние поля и поля, скопированные из родителя, или
  2. создать представление для дочернего элемента, которое включает в себя как поля родителя, так и дочерние элементы, и выразить уникальное ограничение для этого представления.

Вам придется либо сделать это вручную, либо разработать собственную структуру для автоматического вставки/изменения/удаления этих ограничений.

+0

Я считаю, что вы [не можете копировать поля родительской модели в наследующих моделях] (https : //docs.djangoproject.com/en/1.10/topics/db/models/#field-name-hiding-is-not-permitted), поэтому вариант 1 не работает. –

+0

Вы не можете скопировать родительские поля, чтобы они имели одинаковое имя поля в дочерней модели в Django, но вы можете скопировать их в новое имя поля в дочерней модели. Я думаю, вы можете настроить триггеры базы данных, чтобы следить за сохранением скопированных полей. Ограничение затем выражается в скопированном поле в дочерней модели, как описано выше. (Я не говорю это красиво! Но это возможно) – jcdude

+0

О, я вижу логику, которая действительно сработает. В конечном счете, если django_polymorphic был настроен для работы с абстрактными базовыми моделями, он работал бы без взлома его, но, похоже, не было никаких планов поддержать это. –

Смежные вопросы