Django PositiveIntegerField接受否定

Ewa*_*wan 3 python django django-models

我的Django应用程序(视图)中有一个带有PositiveIntegerField的模型:

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)
Run Code Online (Sandbox Code Playgroud)

但是,当我测试它时,它接受负值:

测试:

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)
Run Code Online (Sandbox Code Playgroud)

失败:

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)
Run Code Online (Sandbox Code Playgroud)

我在这里做错了吗?

我尝试用int(-10)和int(" - 10")测试它,这是一个字符串格式错误我得到了很多.

catavaran的回答包括:

post.full_clean()
Run Code Online (Sandbox Code Playgroud)

也失败了.

cat*_*ran 8

以下是文档验证对象章节的摘录:

请注意,full_clean()不会被自动调用,当你调用模型的save()方法.如果要为自己手动创建的模型运行一步模型验证,则需要手动调用它.

因此验证和保存模型应如下所示:

post = Post(author=test_user_profile, title='Django Testing',
            content='hello world', views=-10)
post.full_clean()
post.save()
Run Code Online (Sandbox Code Playgroud)

更新:似乎关闭了SQLite后端的验证.我在django.db.backends.sqlite3.operations.DatabaseOperations课堂上发现了这段代码.

def integer_field_range(self, internal_type):
    # SQLite doesn't enforce any integer constraints
    return (None, None)
Run Code Online (Sandbox Code Playgroud)

此方法的值用于构建验证器PositiveIntegerField.

据我所知,这是出于兼容性原因.因此,如果您想使用SQLite,则必须手动添加验证器:

from django.core.validators import MinValueValidator

class Post(models.Model):
    ...
    views = models.PositiveIntegerField(default=0,
                                        validators=[MinValueValidator(0)])
Run Code Online (Sandbox Code Playgroud)

在此修改之后,full_clean()应该按预期工作.