On Wed, Jan 6, 2010 at 12:49 PM, Simon Willison <[email protected]> wrote:
> A couple of related tickets filed today about model validation:
>
> http://code.djangoproject.com/ticket/12513
> http://code.djangoproject.com/ticket/12521
>
> The first one describes the issue best - the new model validation code
> breaks the following common Django convention:
>
> form = SecretQuestionForm( {"secret_question":"foo", "answer":"bar"} )
> if form.is_valid():
>    p = form.save(commit=False)
>    p.user = request.user
>    p.primary_contact = somecontact
>    p.save()
>
> The problem is that is_valid() notices that some of the required
> fields in SecretQuestionForm (a ModelForm) have not been provided,
> even if those fields are excluded from validation using the excludes=
> or fields= properties. The exception raised is a
> UnresolvableValidationError.

OK. I've attached a patch for another shot at this to #12521 [1].

form.is_valid *should* act like it did before the model-validation
merge. This is trickier than it sounds though, and there are probably
a few more corner cases. ModelForm validation uses validation from
model fields and validators, not just the form fields, so simply
skipping validation for excluded fields isn't enough.

model.full_validate() is *only* for validating an entire model. It
calls validate_fields, validate_unique, the the validate hook in
order.

model.validate_fields(fields=None)
Validate the fields specified, or all fields if fields is None. fields
should be a list of field names.

model.validate_unique(fields=None)
Validate the uniqueness of the specified fields, or all fields if
fields is None. fields should be a list of field names.

    form = SecretQuestionForm( {"secret_question":"foo", "answer":"bar"} )
    if form.is_valid():
        p = form.save(commit=False)
        p.user = request.user
        p.primary_contact = somecontact
        # You probably won't actually want to run model validation this
        # way, but hopefully this shows what ModelForm isn't doing.
        try:
            # Run validation that was missed by the form.
            p.validate_fields(fields=['user', 'primary_contact'])
            p.validate_unique(fields=['user', 'primary_contact'])
            p.validate()
            # Or run *all* validation again.
            p.full_validate()
        except ValidationError, e:
            pass
            # I don't know how you'd even really recover from error here.
            # it's too late to show any form errors. At least you
            # know your model is valid before saving though.
        p.save()

Thoughts?

Joseph

[1] http://code.djangoproject.com/ticket/12521
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.


Reply via email to