如何测试是否创建了 django 模型的实例?

How to test if an instance of a django model was created?

我正在测试一个 api 游戏,但模型有一些问题。

这是我的模型:

models.py

class Gamesession(models.Model):
    gamemode = models.ForeignKey(Gamemode, on_delete=models.CASCADE, null=True)
    user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
    gametype = models.ForeignKey(Gametype, on_delete=models.CASCADE)
    created = models.DateTimeField(editable=False)

    objects = models.Manager()

这是测试套件:

test_models.py

    def setUp(self):
        self.user = CustomUser.objects.create(id=1, username="carina")
        self.gametype = Gametype.objects.create(id=1, name="NewGame", rounds=5, round_duration=60, enabled=True)
        self.gamesession_user = self.user
        self.gamesession_gametype = self.gametype
        self.gamesession_created = datetime.utcnow().replace(tzinfo=pytz.UTC)
        self.gamesession = Gamesession.objects.create(id=1,
                                                      user=self.gamesession_user,
                                                      gametype=self.gamesession_gametype,
                                                      created=self.gamesession_created)

    def test_create_gamesession(self):
        gamesession = Gamesession.objects.create(gametype=self.gametype)
        assert gamesession.gametype == self.gamesession_gametype

运行 我的测试不断检索错误:GamesessionTests::test_create_gamesession - django.db.utils.IntegrityError:关系“frontend_games

的“创建”列中的空值

我该如何解决这个问题?有没有更好的方法来测试是否创建了模型实例?

发生这种情况是因为您将 created 定义为不是 null=True 且没有任何 default=… 的字段,因此这意味着它没有为其分配适当的值。因此,您可以构造对象:

def test_create_gamesession(self):
    gamesession = Gamesession.objects.create(
        gametype=self.gametype,
        <strong>gamesession_created=self.gamesession_created</strong>
    )
    assert gamesession.gametype == self.gamesession_gametype

你可能不想指定一个值,你可以利用auto_now_add=True [Django-doc]指定Django在创建对象时应该填写时间戳:

class Gamesession(models.Model):
    # …
    created = models.DateTimeField(<strong>auto_now_add=True</strong>)

这也会使字段 non-editable。