Порядок создания модели при тестировании в Django? - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть эти две модели (примеры), и когда я пытаюсь запустить свои тесты - он выдает ошибку, говоря: no such table: my_app_modelA - если я прокручиваю вверх, я вижу, что он взрывается при создании modelB (что я предполагаю, из-за применения default). Есть ли способ заказать их так, чтобы modelA всегда создавался до modelB? Или я не должен ссылаться на этот метод в качестве атрибута по умолчанию? Просто пытаюсь заставить мои тесты работать, и это моя точка отсчета.

Мои модели выглядят так:

class modelA(models.Model):
    attribute = models.IntegerField()
    active = models.BooleanField(default=False)

    @classmethod
    def get_active_attribute(cls):
        return modelA.objects.get(active=True).attribute

class modelB(models.Model):
    attribute = models.IntegerField(default=modelA.get_active_attribute())

Мои вопросы:

  • Разве это приемлемо - по умолчанию вызывать другой метод модели?

  • Есть ли способ справиться с созданием этих моделей таким образом, чтобы я мог гарантировать, что modelA будет создан первым, чтобы modelB мог успешно создать в моих тестах?

1 Ответ

1 голос
/ 16 апреля 2019

Прежде всего, миграции происходят в порядке, который определяется при создании файла миграции.

# 0001_initial.py
...
operations = [
    migrations.CreateModel(
        name=modelA,
        ....
    ),
    migrations.CreateModel(
        name=modelB,
        ....
    ),
]

Вы можете проверить файлы миграции и убедиться, что modelA раньше modelB.

Во-вторых, modelA.get_active_attribute() нужна запись в БД, чтобы иметь возможность что-то вернуть. Во время выполнения миграции вы не вставляете данные. Таким образом, вы не должны объявлять default объектом другой модели. Вместо этого вы должны переопределить save(), чтобы убедиться, что значение по умолчанию основано на атрибуте modelA.

class modelB(models.Model):
    attribute = models.IntegerField()

    def save(self, *args, **kwargs):
        if self.attribute is None:
            self.attribute = modelA.get_active_attribute()
        super(modelB, self).save(*args, **kwargs)
...