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.