id summary reporter owner description type status component version severity resolution keywords cc stage has_patch needs_docs needs_tests needs_better_patch easy ui_ux 24988 Document raising a dictionary of ValidationErrors Michael Barr Tim Graham "Assuming the following model: {{{ class DateRange(models.Model): start = models.DateField() end = models.DateField() def clean(self): super(DateRange, self).clean() if self.start and self.end: if self.start >= self.end: raise ValidationError( message={ 'start': _( '{start} must come before {end}.'.format( start=self._meta.get_field( 'start' ).verbose_name, end=self._meta.get_field( 'end' ).verbose_name, ) ), 'end': _( '{end} must come after {start}.'.format( end=self._meta.get_field( 'end' ).verbose_name, start=self._meta.get_field( 'start' ).verbose_name, ) ), }, code='invalid', ) }}} After then validating the model with a ModelForm, the `code` fails to be set to `'invalid'` but is instead an empty string. I discovered this when I was programming tests: {{{ def test_start_before_end_validation(self): """"""Start date must come before end date."""""" TestForm = modelform_factory( model=DateRange, fields=('start', 'end') ) form = TestForm( data=dict( start=date(2015, 1, 1), end=date(1900, 12, 31) # WHOOPS! ) ) self.assertEqual(first=form.is_valid(), second=False) # The below fails because the code is '' - we have to leave off the code self.assertTrue(form.has_error(field='start'), code='invalid') self.assertTrue(form.has_error(field='end'), code='invalid') }}} Upon inspection of the the `ValidationError` code, I discovered that that any `ValidationError` that is raised with a type of `dict` or a `list` as the `message` will never set the code: {{{ if isinstance(message, dict): self.error_dict = {} for field, messages in message.items(): if not isinstance(messages, ValidationError): messages = ValidationError(messages) self.error_dict[field] = messages.error_list elif isinstance(message, list): self.error_list = [] for message in message: # Normalize plain strings to instances of ValidationError. if not isinstance(message, ValidationError): message = ValidationError(message) if hasattr(message, 'error_dict'): self.error_list.extend(sum(message.error_dict.values(), [])) else: self.error_list.extend(message.error_list) }}} According to the [https://docs.djangoproject.com/en/1.8/ref/forms/validation/#raising-validationerror documentation on raising ValidationError], it is suggested to ""Provide a descriptive error code to the constructor."" Is this a bug? I believe the ""fix"" would be as simple as to pass `code=code` following the message/messages, but I may be wrong. Thoughts?" Cleanup/optimization closed Documentation 1.8 Normal fixed ValidationError Loic Bistuer Accepted 1 0 0 1 0 0