> > On 11/7/07, David Larlet <[EMAIL PROTECTED]> wrote:
> >> Hi all,
> >>
> >> I'd spent a long time finding that bug but I want to be sure before
> >> submitting it on Trac. If you pass a form argument to form_for_instance
> >> like that:
> >>
> >> forms.form_for_instance(foo, form=FooForm)
> >>
> >> with an instance of foo which only contains a basic field (let's say a
> >> CharField) and FooForm with a unique field too, the input rendered will
> >> not be completed with the content of the foo instance. If you remove the
> >> form argument:
> >>
> >> forms.form_for_instance(foo)
> >>
> >> the generated form contains the content of the foo instance.
> >>
> >> I'd tried to find the bug but this line (122 of newforms.models):
> >>
> >>     return type(opts.object_name + 'InstanceForm', (form,),
> >>         {'base_fields': base_fields, '_model': model,
> >>          'save': make_instance_save(instance, fields, 'changed')})
> >>
> >> give me headaches ;-). The only thing I can say is that base_fields
> >> contains the initial data before this line but my returned form not.
> >>
> >> Did somebody use this argument and can confirm?

I can confirm that it does in fact work as you describe, but I don't
believe it's a bug. The only documentation I was able to find on this
argument is in the docstrings for form_for_model and
form_for_instance, both of which clearly state that it's intended to
receive a subclass of BaseForm, not Form.

Here's the difference.

BaseForm is what provides all the real functionality for the form:
iterating over fields, triggering HTML output, managing validation,
etc. It's not normally used outside of Django's internals, because the
Form class subclasses it already. However, it doesn't know anything
about how to get the fields for the form. Instead, the Form class uses
a special way to pull fields out of the class definition and assign
them where they belong. form_for_model and form_for_instance don't
need this syntax, so they bypass that step by directly assigning the
fields where they belong when they create the class.

When you pass in a subclass of Form, it's already got its fields in
the right place, but more importantly, it triggers that syntax
checking again, where it looks for new fields. It basically copies
fields from a parent class, then adds in the fields that it found in
the new class. However, since form_for_model and form_for_instance
don't supply any fields that way, all it gives the new form is what it
found in the parent class, completely overwriting the fields it got
from form_for_*.

That was a bit of a long explanation, but I think it's necessary to
know what's going on, and it leaves me with two more points.

As for what that form argument was meant for, it's designed for a
BaseForm subclass. This allows you to add *methods* to your generated
form, not new fields.

As for what you're trying to do, check out the 'fields' argument to
form_for_instance. It creates a form with just a subset of the fields
from the original model.

-Gul

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
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