Определите ForeignKey для модели перед определением этой модели - PullRequest
0 голосов
/ 09 января 2019

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

class Question(models.Model):
    """Model for question."""

    question_text = models.TextField(blank=True, null=True)
    answer = models.ForeignKey(Option, on_delete=models.PROTECT)  # Can't do this


class Option(models.Model):
    """Model for options of a question."""

    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    text = models.CharField(max_length=127)

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

Обновление

Подумав немного, я разобрался со структурой модели, которую могу использовать, мне нужна еще одна модель для ответов.

class Question(models.Model):
    """Model for question."""
    ...


class Option(models.Model):
    """Model for options of a question."""
    ...

class Answer(models.Model):
    """Model for answers."""

    question = models.OneToOneField(Question, on_delete=models.CASCADE)
    answer = models.ForeignKey(Option, on_delete=models.PROTECT)

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

1 Ответ

0 голосов
/ 09 января 2019

Вот как я бы переписал ваш пример кода:

class Question(models.Model):
    """Model for question."""

    question_text = models.TextField(blank=True, null=True)
    answer = models.ForeignKey(<b>'Option'</b>, on_delete=models.PROTECT)  # Can't do this


class Option(models.Model):
    """Model for options of a question."""

    question = models.ForeignKey(<b>'Question'</b>, on_delete=models.CASCADE)
    text = models.CharField(max_length=127)

Обратите внимание на первый аргумент (выделен жирным шрифтом), переданный ForeignKey. Это строка с названием модели.

Если вы посмотрите официальную документацию Django для foreignkey , вы увидите, что это объясняется там:

Если вам нужно создать связь на модели, которая еще не была определена, вы можете использовать имя модели, а не сам объект модели

Лично я считаю, что это хорошая практика, и последовательно использую ее во всех модельных классах, независимо от того, в каком порядке они определены. Преимущество заключается в том, что при рефакторинге кода вам не нужно думать о заказе.

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


class Foo(models.Model):
    bar = models.ForeignKey('baz.SomeModel', on_delete=models.DO_NOTHING)

без явного импорта модуля, например:

from baz.models import SomeModel
...