首页 > 解决方案 > 为什么 django 不需要所有字段来测试模型

问题描述

我有一个这样的模型:

class CreateDeal(models.Model):
    name = models.CharField(max_length=100)
    fuel = models.CharField(max_length=15)
    mileage = models.PositiveIntegerField(db_index=True)
    phone_number = models.CharField(max_length=17) 
    location = models.CharField(max_length=100, db_index=True)
    car_picture = models.ImageField(upload_to='car_picture')
    description = models.TextField()
    price = models.PositiveSmallIntegerField(db_index=True)
    available = models.BooleanField(default=True)
    created_on = models.DateTimeField(default=timezone.now)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    
    def __str__(self):
        return self.name

我有一个测试类来测试上面的模型,如下所示:

class CreateDealTest(TestCase):
    def setUp(self):
        self.user = User.objects.create_user(
            username='alfa', email='alfa@hotmail.com', password='top_secret'
        )
        self.deal = CreateDeal.objects.create(
            name='deal1', mileage=100, price=25, user=self.user
        )

    def test_deal_name(self):
        deal = CreateDeal.objects.get(name='deal1')
        expected_deal_name = f'{self.deal.name}'
        self.assertAlmostEqual(expected_deal_name, str(deal))

如果我运行测试,我有:

Ran 1 test in 0.166s

OK

我的问题是为什么 django 不引发异常,因为我模型中的几乎所有字段都是必需的。我不明白的是,如果我删除我的一个字段CreatedealsetUp如里程、价格、用户或名称),我有一个错误。

例如,如果我删除mileage,我有这个错误:

提高 utils.IntegrityError(*tuple(e.args))

django.db.utils.IntegrityError: (1048, "列'里程'不能为空")

标签: djangounit-testingmodel

解决方案


Charfield、Imagefield 和 Textfield 可以是在数据库级别有效的空字符串,您的某些字段具有默认值,因此如果未设置它们将被写入,从而使它们在数据库级别也有效。

PositiveIntegerField 和 Foreign key 不能设置为空字符串,只能设置为 value 或 null,因此null=False默认情况下它们将失败。

默认blank=False选项仅适用于验证级别,而不适用于数据库级别。这意味着如果你调用full_clean()你的模型,它将引发一个ValidationError. 但是没有什么能阻止你保存一个无效的模型(save()不调用这里full_clean()解释的)。


推荐阅读