Подтвердить что ты не робот

Настройка внешнего ключа для абстрактного базового класса с помощью Django

Я использовал обобщенные атрибуты из двух классов в абстрактный базовый класс, однако у меня есть еще одна модель, которая должна ссылаться на один из этих классов. Невозможно ссылаться на ABC, поскольку на самом деле нет таблицы базы данных.

Следующий пример должен проиллюстрировать мою проблему:

class Answer(models.Model):
    ovramt = models.ForeignKey("Ovramt")
    question = models.ForeignKey("Question")
    answer = models.CharField(max_length=3, choices=(("yes","yes"),("no","no") ("NA","N/A"))
    likelihood = models.IntegerField(choices=LIKELY_CHOICES)
    consequence = models.IntegerField(choices=CONSEQUENCE_CHOICES)

    class Meta:
        abstract = True

class Answer_A(Answer):
    resident = models.ForeignKey("Resident")
    def __unicode__(self):
        return u"%s - %s - %s" %(self.ovramt.ssa.name, self.resident, self.question)    

class Answer_B(Answer):
    def __unicode__(self):
        return u"%s - %s" %(self.ovramt.ssa.name, self.question)    

class Answer_Risk(models.Model):
    answer = models.ForeignKey("Answer")
    risk = models.CharField(max_length=200)

    def __unicode__(self):
        return self.risk

Answer_A и Answer_B немного отличаются в том, что Answer_A также требует отношения FK к другой таблице. Answer_B может также потребовать некоторые конкретные атрибуты позже. Проблема будет STILL, если бы у меня был Answer_B суперкласс - и иметь подкласс Answer_A или составить его.

A "Риск" - это то же самое, что оно: Answer_A или Answer_B. У меня также есть другие модели, которые должны ссылаться на "Ответ", независимо от того, какой тип подтипа. Как это может быть сделано? Как вы можете ссылаться на тип независимо от его подтипа?

Обновление:
Я пытался избежать операции присоединения, но я не думаю, что смогу. Стоит ли иметь ссылку на "Резидент" во всем "Ответ" и просто обнулять его там, где это необходимо? Или это считается очень плохой практикой?

4b9b3361

Ответ 1

A родовое отношение, кажется, является решением. Но это еще больше осложнит ситуацию.

Мне кажется; ваша структура модели уже более сложна, чем необходимо. Я бы просто объединил все три модели Answer в один. Таким образом:

  • Answer_Risk будет работать без изменений.
  • Вы можете установить resident значение None (NULL) в случае Answer_A.
  • Вы можете возвращать различные строки в зависимости от resident == None. (другими словами, такая же функциональность)

Еще одна вещь; Ваши ответы могут иметь более одного риска? Если у них не будет ни одного или одного риска, вам следует рассмотреть следующие альтернативные варианты:

  • Использование отношения один к одному
  • Снижение риска в виде поля (или любого количества полей) внутри класса Answer.

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

Ответ 2

Моя интуиция - предложить удалить абстрактный модификатор в базовом классе. Вы получите ту же структуру модели, но ответом будет собственная таблица. Недостатком этого является то, что если это большие таблицы и/или ваши запросы сложны, запросы к ним могут быть заметно медленнее.

В качестве альтернативы вы можете оставить ваши модели как есть, но замените ForeignKey для ответа на GenericForeignKey. То, что вы потеряете в синтаксическом сахаре наследования моделей, вы немного увеличите в скорости запросов.

Я не верю, что можно ссылаться на абстрактную базовую модель с помощью ForeignKey (или что-либо функционально то же самое).