Ticket #16986: model-clean-errordict-3.diff

File model-clean-errordict-3.diff, 5.3 KB (added by David Foster, 8 years ago)
  • tests/modeltests/validation/tests.py

     
    88
    99from . import ValidationTestCase
    1010from .models import (Author, Article, ModelToValidate,
    11     GenericIPAddressTestModel, GenericIPAddrUnpackUniqueTest)
     11    GenericIPAddressTestModel, GenericIPAddrUnpackUniqueTest, Range)
    1212# Import other tests for this package.
    1313from .test_custom_messages import CustomMessagesTest
    1414from .test_error_messages import ValidationMessagesTest
     
    190190        giptm.save()
    191191        giptm = GenericIPAddrUnpackUniqueTest(generic_v4unpack_ip="18.52.18.52")
    192192        self.assertFailsValidation(giptm.full_clean, ['generic_v4unpack_ip',])
     193
     194class RangeForm(forms.ModelForm):
     195    class Meta:
     196        model = Range
     197
     198class ModelCleanPerFieldValidationTests(ValidationTestCase):
     199   
     200    def test_no_errors(self):
     201        range = Range(min=0, max=1)
     202        range.full_clean()
     203       
     204        form = RangeForm(instance=range)
     205        form.full_clean()
     206        self.assertEqual({}, form.errors)
     207   
     208    def test_two_errors(self):
     209        range = Range(min=999, max=1)
     210        self.assertFieldFailsValidationWithMessage(range.full_clean, 'min', [u'Min value must be less that or equal to the max value.'])
     211        self.assertFieldFailsValidationWithMessage(range.full_clean, 'max', [u'Max value must be greater than or equal to the min value.'])
     212       
     213        # In particular, the key should not be '__all__'
     214        expected_error_dict = {
     215            'min': [u'Min value must be less that or equal to the max value.'],
     216            'max': [u'Max value must be greater than or equal to the min value.'],
     217        }
     218        form = RangeForm(data={'min': 999, 'max': 1})
     219        form.full_clean()
     220        self.assertEqual(expected_error_dict, form.errors)
  • tests/modeltests/validation/models.py

     
     1from collections import defaultdict
    12from datetime import datetime
    23
    34from django.core.exceptions import ValidationError
     
    9293class GenericIPAddrUnpackUniqueTest(models.Model):
    9394    generic_v4unpack_ip = models.GenericIPAddressField(blank=True, unique=True, unpack_ipv4=True)
    9495
     96class Range(models.Model):
     97    min = models.IntegerField()
     98    max = models.IntegerField()
     99   
     100    def clean(self):
     101        message_dict = defaultdict(list)
     102        if self.min and self.max and (not self.min <= self.max):
     103            message_dict['min'].append(u'Min value must be less that or equal to the max value.')
     104            message_dict['max'].append(u'Max value must be greater than or equal to the min value.')
     105        if len(message_dict):
     106            raise ValidationError(message_dict)
    95107
    96108# A model can't have multiple AutoFields
    97109# Refs #12467.
     
    102114        auto2 = models.AutoField(primary_key=True)
    103115except AssertionError, assertion_error:
    104116    pass # Fail silently
    105 assert str(assertion_error) == u"A model can't have more than one AutoField."
    106  No newline at end of file
     117assert str(assertion_error) == u"A model can't have more than one AutoField."
  • django/forms/models.py

     
    331331        try:
    332332            self.instance.clean()
    333333        except ValidationError, e:
    334             self._update_errors({NON_FIELD_ERRORS: e.messages})
     334            if e.has_message_dict:
     335                self._update_errors(e.message_dict)
     336            else:
     337                self._update_errors({NON_FIELD_ERRORS: e.messages})
    335338
    336339        # Validate uniqueness if needed.
    337340        if self._validate_unique:
  • django/core/exceptions.py

     
    5959            self.params = params
    6060            message = force_unicode(message)
    6161            self.messages = [message]
    62 
     62   
     63    @property
     64    def has_message_dict(self):
     65        return hasattr(self, 'message_dict')
     66   
    6367    def __str__(self):
    6468        # This is needed because, without a __str__(), printing an exception
    6569        # instance would result in this:
    6670        # AttributeError: ValidationError instance has no attribute 'args'
    6771        # See http://www.python.org/doc/current/tut/node10.html#handling
    68         if hasattr(self, 'message_dict'):
     72        if self.has_message_dict:
    6973            return repr(self.message_dict)
    7074        return repr(self.messages)
    7175
    7276    def __repr__(self):
    73         if hasattr(self, 'message_dict'):
     77        if self.has_message_dict:
    7478            return 'ValidationError(%s)' % repr(self.message_dict)
    7579        return 'ValidationError(%s)' % repr(self.messages)
    7680
    7781    def update_error_dict(self, error_dict):
    78         if hasattr(self, 'message_dict'):
     82        if self.has_message_dict:
    7983            if error_dict:
    8084                for k, v in self.message_dict.items():
    8185                    error_dict.setdefault(k, []).extend(v)
Back to Top