【问题标题】:Model creation order when testing in django?在 django 中测试时的模型创建顺序?
【发布时间】:2019-04-16 12:24:00
【问题描述】:

我有这两个模型(示例),当我试图运行我的测试时 - 它错误地说: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 可以在我的测试中成功创建?

【问题讨论】:

    标签: python django python-3.x testing


    【解决方案1】:

    首先,迁移按照创建迁移文件时定义的顺序进行。

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

    您可以检查您的迁移文件并确保modelAmodelB 之前。

    其次,modelA.get_active_attribute() 需要一个 DB 条目才能返回某些内容。运行迁移时,您不会插入数据。所以你不应该用其他模型的对象声明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)
    

    【讨论】:

    • 我相信这是正确的答案。迁移的创建方式是,modelA 迁移是在 modelB 之后创建的,但在初始迁移中它使用静态 Integer。直到很久以后的更改,以前的开发人员才将其更改为使用该方法。现在,在看到您的答案之后,这在实践中似乎是一个坏主意。在生产中,总是会有一个 DB 条目来返回一些东西——除非很明显——在测试中,这就是我所处的位置。试图在测试中解决这个问题。感谢您的意见!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2017-08-10
    • 2011-02-04
    相关资源
    最近更新 更多