2015-03-15 3 views
2

У меня есть модель с PositiveIntegerField в моем приложении 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) 

Однако, когда я проверить это, он принимает отрицательные значения:

Тест:

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

Проверка положительности выполняется на уровне базы данных, и SQLite-движок не проверяет его вообще. Он был изменен в версии 1.7, в какой версии django вы используете? – GwynBleidD

+0

Использование Django 1.7 – Ewan

ответ

6

Вот отрывок из validating objects главы из документации:

Обратите внимание, что full_clean() будет не вызывается автоматически при вызове метода save() вашей модели. Вам нужно будет называть это вручную, если вы хотите выполнить одноэтапную проверку модели для своих созданных вручную моделей.

Так проверки и сохранения модель должна выглядеть следующим образом:

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

UPDATE: Похоже, эта проверка выключена для 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() должен работать, как ожидалось.

+0

Модель по-прежнему принимает отрицательные значения, используя приведенный выше фрагмент. – Ewan

+0

Использование 'full_clean()', 'clean()' или 'clean_fields()' не генерирует никаких исключений и сообщений об ошибках не сообщается. – Ewan

+0

Это замечательно, спасибо. Я предположил, что PositiveIntegerFields проверяется автоматически. – Ewan

Смежные вопросы