我的Django应用程序中有一个带有PositiveIntegerField的模型(views):
class Post(models.Model):
author = models.ForeignKey('UserProfile')
creation_date = models.DateTimeField(auto_now_add=True)
views = models.PositiveIntegerField(default=0)
tags = models.ManyToManyField('Tag', through="PostTagging", null=False, blank=False)
rating = models.FloatField(default=0)
然而,当我测试它时,它接受负值:
测试:
def test_post_with_negative_views(self):
test_user = User.objects.get(username='test_student')
test_user_profile = UserProfile.objects.get(user=test_user)
post = Post.objects.create(author=test_user_profile, title='Django Testing', content='hello world', views=-10)
self.assertEquals(post.views, 0)
故障:
Creating test database for alias 'default' ...
......F.......
=====================================================================
FAIL: test_post_with_negative_views (bark.tets.PostTest)
---------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ewan/Documents/WAD2/studeso/bark/bark/tests.py", line 58, in test_post_with_negative_views
self.assertEquals(post.views, 0)
AssertionError: -10 != 0
---------------------------------------------------------------------
FAILED (failures=1)
我在这里做错了吗?
我尝试用int(-10)和int(" -10")测试它,因为这是一个字符串格式错误我得到了很多。
catavaran的答案包括:
post.full_clean()
也失败了。
答案 0 :(得分:8)
以下是文档validating objects章节的摘录:
请注意,当您调用模型的
full_clean()
方法时,save()
将不会自动调用。如果要为自己手动创建的模型运行一步模型验证,则需要手动调用它。
因此验证和保存模型应如下所示:
post = Post(author=test_user_profile, title='Django Testing',
content='hello world', views=-10)
post.full_clean()
post.save()
更新:似乎已为SQLite后端关闭此验证。我在django.db.backends.sqlite3.operations.DatabaseOperations
类中找到了此代码。
def integer_field_range(self, internal_type):
# SQLite doesn't enforce any integer constraints
return (None, None)
此方法的值用于构建PositiveIntegerField
的验证程序。
据我所知,这是出于兼容性原因。因此,如果您想使用SQLite,则必须手动添加验证器:
from django.core.validators import MinValueValidator
class Post(models.Model):
...
views = models.PositiveIntegerField(default=0,
validators=[MinValueValidator(0)])
修改完成后,full_clean()
应按预期工作。