mirror of
https://github.com/django/django.git
synced 2025-07-07 03:09:22 +00:00
[soc2009/model-validation] Renamed Model's clean method to full_validate to be more consistent with django.forms.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@12039 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c2a2b51ac3
commit
a907e15cad
@ -644,7 +644,7 @@ class Model(object):
|
|||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
"""
|
"""
|
||||||
Hook for doing any extra model-wide validation after Model.clean() been
|
Hook for doing any extra model-wide validation after clean() has been
|
||||||
called on every field. Any ValidationError raised by this method will
|
called on every field. Any ValidationError raised by this method will
|
||||||
not be associated with a particular field; it will have a special-case
|
not be associated with a particular field; it will have a special-case
|
||||||
association with the field named '__all__'.
|
association with the field named '__all__'.
|
||||||
@ -785,7 +785,7 @@ class Model(object):
|
|||||||
'field_label': unicode(field_labels)
|
'field_label': unicode(field_labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
def clean(self, exclude=[]):
|
def full_validate(self, exclude=[]):
|
||||||
"""
|
"""
|
||||||
Cleans all fields and raises ValidationError containing message_dict of
|
Cleans all fields and raises ValidationError containing message_dict of
|
||||||
all validation errors if any occur.
|
all validation errors if any occur.
|
||||||
|
@ -244,7 +244,7 @@ class BaseModelForm(BaseForm):
|
|||||||
opts = self._meta
|
opts = self._meta
|
||||||
self.instance = make_instance(self, self.instance, opts.fields, opts.exclude)
|
self.instance = make_instance(self, self.instance, opts.fields, opts.exclude)
|
||||||
try:
|
try:
|
||||||
self.instance.clean(exclude=self._errors.keys())
|
self.instance.full_validate(exclude=self._errors.keys())
|
||||||
except ValidationError, e:
|
except ValidationError, e:
|
||||||
for k, v in e.message_dict.items():
|
for k, v in e.message_dict.items():
|
||||||
if k != NON_FIELD_ERRORS:
|
if k != NON_FIELD_ERRORS:
|
||||||
@ -272,7 +272,6 @@ class BaseModelForm(BaseForm):
|
|||||||
fail_message = 'created'
|
fail_message = 'created'
|
||||||
else:
|
else:
|
||||||
fail_message = 'changed'
|
fail_message = 'changed'
|
||||||
|
|
||||||
return save_made_instance(self, self.instance, self._meta.fields, commit, fail_message)
|
return save_made_instance(self, self.instance, self._meta.fields, commit, fail_message)
|
||||||
|
|
||||||
save.alters_data = True
|
save.alters_data = True
|
||||||
|
@ -32,9 +32,9 @@ Validating objects
|
|||||||
|
|
||||||
.. versionadded:: 1.2
|
.. versionadded:: 1.2
|
||||||
|
|
||||||
To validate your model, just call it's ``clean()`` method:
|
To validate your model, just call it's ``full_validate()`` method:
|
||||||
|
|
||||||
.. method:: Model.clean([exclude=[]])
|
.. method:: Model.full_validate([exclude=[]])
|
||||||
|
|
||||||
The optional ``exclude`` argument can contain a list of field names that should
|
The optional ``exclude`` argument can contain a list of field names that should
|
||||||
be omitted when validating. This method raises ``ValidationError`` containing a
|
be omitted when validating. This method raises ``ValidationError`` containing a
|
||||||
@ -45,8 +45,9 @@ To add your own validation logic, override the supplied ``validate()`` method:
|
|||||||
.. method:: Model.validate()
|
.. method:: Model.validate()
|
||||||
|
|
||||||
The ``validate()`` method on ``Model`` by default checks for uniqueness of
|
The ``validate()`` method on ``Model`` by default checks for uniqueness of
|
||||||
fields and group of fields that are declared to be unique so remember to call
|
fields and group of fields that are declared to be unique so, remember to call
|
||||||
``super.validate()`` if you want this validation to run.
|
``self.validate_unique()`` or the superclasses ``validate`` method if you want
|
||||||
|
this validation to run.
|
||||||
|
|
||||||
Any ``ValidationError`` raised in this method will be propagated in the
|
Any ``ValidationError`` raised in this method will be propagated in the
|
||||||
``message_dict`` under ``NON_FIELD_ERRORS``.
|
``message_dict`` under ``NON_FIELD_ERRORS``.
|
||||||
|
@ -4,13 +4,13 @@ from models import CustomMessagesModel
|
|||||||
class CustomMessagesTest(ValidationTestCase):
|
class CustomMessagesTest(ValidationTestCase):
|
||||||
def test_custom_complex_validator_message(self):
|
def test_custom_complex_validator_message(self):
|
||||||
cmm = CustomMessagesModel(number=42, other=42)
|
cmm = CustomMessagesModel(number=42, other=42)
|
||||||
self.assertFieldFailsValidationWithMessage(cmm.clean, 'number', ['other != me'])
|
self.assertFieldFailsValidationWithMessage(cmm.full_validate, 'number', ['other != me'])
|
||||||
|
|
||||||
def test_custom_simple_validator_message(self):
|
def test_custom_simple_validator_message(self):
|
||||||
cmm = CustomMessagesModel(number=12)
|
cmm = CustomMessagesModel(number=12)
|
||||||
self.assertFieldFailsValidationWithMessage(cmm.clean, 'number', ['AAARGH'])
|
self.assertFieldFailsValidationWithMessage(cmm.full_validate, 'number', ['AAARGH'])
|
||||||
|
|
||||||
def test_custom_null_message(self):
|
def test_custom_null_message(self):
|
||||||
cmm = CustomMessagesModel()
|
cmm = CustomMessagesModel()
|
||||||
self.assertFieldFailsValidationWithMessage(cmm.clean, 'number', ['NULL'])
|
self.assertFieldFailsValidationWithMessage(cmm.full_validate, 'number', ['NULL'])
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ import unittest
|
|||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
|
||||||
from models import CustomPKModel, UniqueTogetherModel, UniqueFieldsModel, UniqueForDateModel, ModelToValidate
|
from models import CustomPKModel, UniqueTogetherModel, UniqueFieldsModel, UniqueForDateModel, ModelToValidate
|
||||||
|
|
||||||
|
|
||||||
class GetUniqueCheckTests(unittest.TestCase):
|
class GetUniqueCheckTests(unittest.TestCase):
|
||||||
def test_unique_fields_get_collected(self):
|
def test_unique_fields_get_collected(self):
|
||||||
m = UniqueFieldsModel()
|
m = UniqueFieldsModel()
|
||||||
@ -26,7 +26,6 @@ class GetUniqueCheckTests(unittest.TestCase):
|
|||||||
), m._get_unique_checks()
|
), m._get_unique_checks()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class PerformUniqueChecksTest(unittest.TestCase):
|
class PerformUniqueChecksTest(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# set debug to True to gain access to connection.queries
|
# set debug to True to gain access to connection.queries
|
||||||
@ -43,12 +42,12 @@ class PerformUniqueChecksTest(unittest.TestCase):
|
|||||||
l = len(connection.queries)
|
l = len(connection.queries)
|
||||||
mtv = ModelToValidate(number=10, name='Some Name')
|
mtv = ModelToValidate(number=10, name='Some Name')
|
||||||
setattr(mtv, '_adding', True)
|
setattr(mtv, '_adding', True)
|
||||||
mtv.clean()
|
mtv.full_validate()
|
||||||
self.assertEqual(l+1, len(connection.queries))
|
self.assertEqual(l+1, len(connection.queries))
|
||||||
|
|
||||||
def test_primary_key_unique_check_not_performed_when_not_adding(self):
|
def test_primary_key_unique_check_not_performed_when_not_adding(self):
|
||||||
"""Regression test for #12132"""
|
"""Regression test for #12132"""
|
||||||
l = len(connection.queries)
|
l = len(connection.queries)
|
||||||
mtv = ModelToValidate(number=10, name='Some Name')
|
mtv = ModelToValidate(number=10, name='Some Name')
|
||||||
mtv.clean()
|
mtv.full_validate()
|
||||||
self.assertEqual(l, len(connection.queries))
|
self.assertEqual(l, len(connection.queries))
|
||||||
|
@ -8,50 +8,51 @@ from validators import TestModelsWithValidators
|
|||||||
from test_unique import GetUniqueCheckTests, PerformUniqueChecksTest
|
from test_unique import GetUniqueCheckTests, PerformUniqueChecksTest
|
||||||
from test_custom_messages import CustomMessagesTest
|
from test_custom_messages import CustomMessagesTest
|
||||||
|
|
||||||
|
|
||||||
class BaseModelValidationTests(ValidationTestCase):
|
class BaseModelValidationTests(ValidationTestCase):
|
||||||
|
|
||||||
def test_missing_required_field_raises_error(self):
|
def test_missing_required_field_raises_error(self):
|
||||||
mtv = ModelToValidate(f_with_custom_validator=42)
|
mtv = ModelToValidate(f_with_custom_validator=42)
|
||||||
self.assertFailsValidation(mtv.clean, ['name', 'number'])
|
self.assertFailsValidation(mtv.full_validate, ['name', 'number'])
|
||||||
|
|
||||||
def test_with_correct_value_model_validates(self):
|
def test_with_correct_value_model_validates(self):
|
||||||
mtv = ModelToValidate(number=10, name='Some Name')
|
mtv = ModelToValidate(number=10, name='Some Name')
|
||||||
self.assertEqual(None, mtv.clean())
|
self.assertEqual(None, mtv.full_validate())
|
||||||
|
|
||||||
def test_custom_validate_method_is_called(self):
|
def test_custom_validate_method_is_called(self):
|
||||||
mtv = ModelToValidate(number=11)
|
mtv = ModelToValidate(number=11)
|
||||||
self.assertFailsValidation(mtv.clean, [NON_FIELD_ERRORS, 'name'])
|
self.assertFailsValidation(mtv.full_validate, [NON_FIELD_ERRORS, 'name'])
|
||||||
|
|
||||||
def test_wrong_FK_value_raises_error(self):
|
def test_wrong_FK_value_raises_error(self):
|
||||||
mtv=ModelToValidate(number=10, name='Some Name', parent_id=3)
|
mtv=ModelToValidate(number=10, name='Some Name', parent_id=3)
|
||||||
self.assertFailsValidation(mtv.clean, ['parent'])
|
self.assertFailsValidation(mtv.full_validate, ['parent'])
|
||||||
|
|
||||||
def test_correct_FK_value_cleans(self):
|
def test_correct_FK_value_validates(self):
|
||||||
parent = ModelToValidate.objects.create(number=10, name='Some Name')
|
parent = ModelToValidate.objects.create(number=10, name='Some Name')
|
||||||
mtv=ModelToValidate(number=10, name='Some Name', parent_id=parent.pk)
|
mtv=ModelToValidate(number=10, name='Some Name', parent_id=parent.pk)
|
||||||
self.assertEqual(None, mtv.clean())
|
self.assertEqual(None, mtv.full_validate())
|
||||||
|
|
||||||
def test_wrong_email_value_raises_error(self):
|
def test_wrong_email_value_raises_error(self):
|
||||||
mtv = ModelToValidate(number=10, name='Some Name', email='not-an-email')
|
mtv = ModelToValidate(number=10, name='Some Name', email='not-an-email')
|
||||||
self.assertFailsValidation(mtv.clean, ['email'])
|
self.assertFailsValidation(mtv.full_validate, ['email'])
|
||||||
|
|
||||||
def test_correct_email_value_passes(self):
|
def test_correct_email_value_passes(self):
|
||||||
mtv = ModelToValidate(number=10, name='Some Name', email='valid@email.com')
|
mtv = ModelToValidate(number=10, name='Some Name', email='valid@email.com')
|
||||||
self.assertEqual(None, mtv.clean())
|
self.assertEqual(None, mtv.full_validate())
|
||||||
|
|
||||||
def test_wrong_url_value_raises_error(self):
|
def test_wrong_url_value_raises_error(self):
|
||||||
mtv = ModelToValidate(number=10, name='Some Name', url='not a url')
|
mtv = ModelToValidate(number=10, name='Some Name', url='not a url')
|
||||||
self.assertFieldFailsValidationWithMessage(mtv.clean, 'url', [u'Enter a valid value.'])
|
self.assertFieldFailsValidationWithMessage(mtv.full_validate, 'url', [u'Enter a valid value.'])
|
||||||
|
|
||||||
def test_correct_url_but_nonexisting_gives_404(self):
|
def test_correct_url_but_nonexisting_gives_404(self):
|
||||||
mtv = ModelToValidate(number=10, name='Some Name', url='http://google.com/we-love-microsoft.html')
|
mtv = ModelToValidate(number=10, name='Some Name', url='http://google.com/we-love-microsoft.html')
|
||||||
self.assertFieldFailsValidationWithMessage(mtv.clean, 'url', [u'This URL appears to be a broken link.'])
|
self.assertFieldFailsValidationWithMessage(mtv.full_validate, 'url', [u'This URL appears to be a broken link.'])
|
||||||
|
|
||||||
def test_correct_url_value_passes(self):
|
def test_correct_url_value_passes(self):
|
||||||
mtv = ModelToValidate(number=10, name='Some Name', url='http://www.djangoproject.com/')
|
mtv = ModelToValidate(number=10, name='Some Name', url='http://www.djangoproject.com/')
|
||||||
self.assertEqual(None, mtv.clean()) # This will fail if there's no Internet connection
|
self.assertEqual(None, mtv.full_validate()) # This will fail if there's no Internet connection
|
||||||
|
|
||||||
def test_text_greater_that_charfields_max_length_eaises_erros(self):
|
def test_text_greater_that_charfields_max_length_eaises_erros(self):
|
||||||
mtv = ModelToValidate(number=10, name='Some Name'*100)
|
mtv = ModelToValidate(number=10, name='Some Name'*100)
|
||||||
self.assertFailsValidation(mtv.clean, ['name',])
|
self.assertFailsValidation(mtv.full_validate, ['name',])
|
||||||
|
|
||||||
|
@ -3,34 +3,34 @@ from unittest import TestCase
|
|||||||
from modeltests.validation import ValidationTestCase
|
from modeltests.validation import ValidationTestCase
|
||||||
from models import *
|
from models import *
|
||||||
|
|
||||||
|
|
||||||
class TestModelsWithValidators(ValidationTestCase):
|
class TestModelsWithValidators(ValidationTestCase):
|
||||||
def test_custom_validator_passes_for_correct_value(self):
|
def test_custom_validator_passes_for_correct_value(self):
|
||||||
mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=42)
|
mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=42)
|
||||||
self.assertEqual(None, mtv.clean())
|
self.assertEqual(None, mtv.full_validate())
|
||||||
|
|
||||||
def test_custom_validator_raises_error_for_incorrect_value(self):
|
def test_custom_validator_raises_error_for_incorrect_value(self):
|
||||||
mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=12)
|
mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=12)
|
||||||
self.assertFailsValidation(mtv.clean, ['f_with_custom_validator'])
|
self.assertFailsValidation(mtv.full_validate, ['f_with_custom_validator'])
|
||||||
self.assertFieldFailsValidationWithMessage(
|
self.assertFieldFailsValidationWithMessage(
|
||||||
mtv.clean,
|
mtv.full_validate,
|
||||||
'f_with_custom_validator',
|
'f_with_custom_validator',
|
||||||
[u'This is not the answer to life, universe and everything!']
|
[u'This is not the answer to life, universe and everything!']
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_custom_complex_validator_raises_error_for_incorrect_value(self):
|
def test_custom_complex_validator_raises_error_for_incorrect_value(self):
|
||||||
mtv = ModelToValidate(number=42, name='Some Name', f_with_custom_validator=42)
|
mtv = ModelToValidate(number=42, name='Some Name', f_with_custom_validator=42)
|
||||||
self.assertFailsValidation(mtv.clean, ['f_with_custom_validator'])
|
self.assertFailsValidation(mtv.full_validate, ['f_with_custom_validator'])
|
||||||
self.assertFieldFailsValidationWithMessage(
|
self.assertFieldFailsValidationWithMessage(
|
||||||
mtv.clean,
|
mtv.full_validate,
|
||||||
'f_with_custom_validator',
|
'f_with_custom_validator',
|
||||||
[u"Must not equal to 'number''s value"]
|
[u"Must not equal to 'number''s value"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_complex_validator_isnt_run_if_field_doesnt_validate(self):
|
||||||
def test_complex_validator_isnt_run_if_field_doesnt_clean(self):
|
|
||||||
mtv = ModelToValidate(number=32, name='Some Name', f_with_custom_validator=32)
|
mtv = ModelToValidate(number=32, name='Some Name', f_with_custom_validator=32)
|
||||||
self.assertFieldFailsValidationWithMessage(
|
self.assertFieldFailsValidationWithMessage(
|
||||||
mtv.clean,
|
mtv.full_validate,
|
||||||
'f_with_custom_validator',
|
'f_with_custom_validator',
|
||||||
[u'This is not the answer to life, universe and everything!']
|
[u'This is not the answer to life, universe and everything!']
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user