Django

Code

Ticket #6652 (reopened)

Opened 3 months ago

Last modified 2 months ago

Allow 'clean()' to specify the wrong field

Reported by: Daniele Varrazzo <piro@develer.com> Assigned to: nobody
Component: django.newforms Version: SVN
Keywords: feature Cc:
Triage Stage: Design decision needed Has patch: 1
Needs documentation: 0 Needs tests: 0
Patch needs improvement: 0

Description

Currently the Form.clean() method has no way to specify which field is invalid, but it's the only place where validation involving many fields can be accomplished. Taking your example in the documentation:

This is where you might put in things to check that if field A is supplied, field B must contain a valid email address and the like.

If the field B doesn't contain a valid email address, the error message should appear next to the B widget, not at the top of the form.

An easy fix is to add a 'field' optional attribute to the ValidationError and use it if provided. I already used this method in other programs of mine (my exception class was called ValidationError too!)

Attachments

field-on-validation-error.patch (1.1 kB) - added by Daniele Varrazzo <piro@develer.com> on 02/23/08 20:39:38.
allow_clean_to_specify_the_wrong_field-with-docs.diff (4.7 kB) - added by mrts on 03/12/08 07:29:21.
allow_clean_to_specify_the_wrong_field-updated-tests-docs.diff (8.3 kB) - added by mrts on 03/20/08 04:18:44.
Appends errors from clean() to original errors.

Change History

02/23/08 20:39:38 changed by Daniele Varrazzo <piro@develer.com>

  • attachment field-on-validation-error.patch added.

02/23/08 20:43:16 changed by Daniele Varrazzo <piro@develer.com>

  • needs_better_patch changed.
  • needs_tests changed.
  • needs_docs changed.

An example of use:

    def clean(self):
        # Check the gateway is compatible with the address/mask
        gateway = self.cleaned_data['gateway']
        address = self.cleaned_data['address']
        netmask = self.cleaned_data['netmask']
        if not netconfig.addresses_match(address, gateway, netmask):
            raise forms.ValidationError(
                "Gateway not valid for the specified address",
                field='gateway')

(follow-up: ↓ 4 ) 02/24/08 02:17:21 changed by russellm

  • status changed from new to closed.
  • resolution set to wontfix.

You're missing the obvious solution - use a clean_field method (eg clean_email()). A field specific clean method can reference other entries from cleaned_data[] if necessary, and any error message will be associated with the field, rather than the form.

02/24/08 02:25:38 changed by mtredinnick

  • summary changed from [feature request] allow 'clean()' to specify the wrong field to Allow 'clean()' to specify the wrong field.

Russell: that does impose an ordering constraint, though -- dependencies done this way can only depend on fields before themselves.

I'd probably be +0 on the patch since it has no backwards compatibility impact. Alternatively, we could document how to add to Form._errors. Leaving closed for now, though.

(in reply to: ↑ 2 ) 02/24/08 05:17:40 changed by Daniele Varrazzo <piro@develer.com>

Replying to russellm:

You're missing the obvious solution - use a clean_field method (eg clean_email()).

Not so obvious: when clean_email() is called you may not have yet the cleaned results of all the fields required for the composed validation.

(follow-up: ↓ 6 ) 02/24/08 05:27:26 changed by russellm

  • keywords set to feature.

Malcolm: Valid point about the ordering requirement, although I'm not convinced that it is a problem in practice. The error message needs to be tied to a specific field, and you can always set up the field order so that the field with the error is last.

This enforces an order for presentation that may not be natural, but only matters if you are rendering using form.as_*; if presentation order doesn't match logical order, you can manually render each field.

My rejection of this idea was based on the fact that it introduces a second way to raise field errors. However, I'm only a -0. Regardless, better documentation of Form._errors is probably a good idea.

(in reply to: ↑ 5 ) 02/24/08 06:07:03 changed by Daniele Varrazzo <piro@develer.com>

Replying to russellm:

My rejection of this idea was based on the fact that it introduces a second way to raise field errors. However, I'm only a -0. Regardless, better documentation of Form._errors is probably a good idea.

Are you sure exposing Form._errors is a good idea? Currently it is an implementation detail (at least for people developing form logic): exposing it in the API is an implementation leak that would tie the current implementation to everybody's form logic.

Adding an optional field to the exception is a (mostly harmless) extension of the current interface.

02/24/08 09:35:28 changed by anonymous

The other point is that when you are composing forms from multiple base forms, you don't always have direct control over ordering unless you redeclare fields (which defeats the purpose of multiple base forms in part).

02/25/08 10:49:01 changed by anonymous

Considering the strong points given, shouldn't this be reopened? I for one would like to use it like in the example above, rather than having to depend on field ordering.

02/28/08 05:11:31 changed by anonymous

  • status changed from closed to reopened.
  • resolution deleted.

02/28/08 08:50:24 changed by jacob

  • stage changed from Unreviewed to Ready for checkin.

02/28/08 08:50:36 changed by jacob

  • needs_docs set to 1.
  • needs_tests set to 1.
  • stage changed from Ready for checkin to Accepted.

03/12/08 07:25:53 changed by mrts

I'm also using this in my projects, so I modified the patch to add tests and documentation (within the tests).

I think it is more clear to use field_name instead of field in the exception (using field is against the DON'T MAKE ME THINK principle: what's a field? instance? name?).

Find the patch attached.

03/12/08 07:29:21 changed by mrts

  • attachment allow_clean_to_specify_the_wrong_field-with-docs.diff added.

03/12/08 07:30:36 changed by anonymous

  • needs_docs deleted.
  • needs_tests deleted.

03/20/08 04:17:54 changed by mrts

  • stage changed from Accepted to Ready for checkin.

Improved patch against [7321] that appends errors from clean() to base field errors.

03/20/08 04:18:44 changed by mrts

  • attachment allow_clean_to_specify_the_wrong_field-updated-tests-docs.diff added.

Appends errors from clean() to original errors.

03/21/08 09:50:21 changed by mtredinnick

  • stage changed from Ready for checkin to Design decision needed.

Given the currently active discussion on django-dev regarding changes to model and form validation (including some renaming), let's sit on this for a bit.


Add/Change #6652 (Allow 'clean()' to specify the wrong field)




Change Properties
Action