Hey Petr, On Jun 3, 11:32 am, "petr.marhoun" <petr.marh...@gmail.com> wrote: > OK, more details: If fieldsets would be defined, fields would be > concatenation of fields from individual fieldsets. So methods > as_table, as_ul and as_li and "for field in form" would work as now. > But if you want to really use fieldsets, you have to iterate fieldsets > in your templates.
Great! I was also planning to propose form fieldsets but hadn't gotten around to it yet. I have an external app, django-form-utils[1], that already implements form fieldsets in very much the way you propose (although with a few differences). The app has seen some use and people seem happy with it; I would be happy to port this implementation to a core patch, with a few changes. One thing form-utils does differently from your proposal is that it defines each fieldset as a two-tuple (like admin fieldsets), with a name as the first element and the dictionary of additional info as the second element. One advantage of having a fieldset "name" is that it also allows accessing fieldsets individually in the template, for more fine-grained layout control (thanks Rob Hudson for adding this to form- utils). Just to give a full summary of the fieldsets API I would propose (which is not exactly the same as what's currently in form-utils; I'd like to correct some mistakes :> ): class PersonForm(forms.Form): name = forms.CharField() age = forms.IntegerField() nickname = forms.CharField() class Meta: fieldsets = [('main', {'fields': ['name', 'age']}), ('extra', {'fields': ['nickname'], 'legend': 'Extra info', 'classes': ['aside']})] (If "fieldsets" is provided for a ModelForm, it takes priority over any "fields" or "exclude" definitions: the fields included in the fieldsets are the ones included in the form, whether you iterate over fieldsets or just fields.) Iterating over the form directly yields BoundFields just as it does now: {% for field in form %} Iterating over form.fieldsets yields Fieldset objects. Fieldset objects can be iterated over to yield BoundFields: {% for fieldset in form.fieldsets %} {% for field in fieldset %} Fieldsets can also be accessed individually by name on form.fieldsets: {% for field in form.fieldsets.main %} And fields can be accessed directly by name on the "fields" attribute of a Fieldset (to avoid clashes between form field names and other Fieldset attribute names): {% form.fieldsets.main.fields.age %} Fieldset objects also have the attributes "name", "legend", and "classes" (which is still an iterable, not collapsed to a string, so template authors can check {% if "blah" in fieldset.classes %} if needed. I am proposing the "classes" option, again parallel to current admin fieldsets, in lieu of any additional options like "attrs" or "template". There's a slippery slope where almost any info _could_ theoretically be provided for the template author by the Python form author; I think it makes sense to keep it to a simple list of class names, as the most basic, generic way to distinguish "types" of fieldsets. I think pretty much any use case can be handled via this mechanism, since you can write custom template tags if needed to provide reusable display logic. (I'd be open to the "attrs" option, but am quite opposed to "template": form definitions seem like entirely the wrong place to embed template names.) I would of course assume that a patch for fieldsets in forms would also involve porting the admin's fieldsets to use this feature. FWIW, I think it would be much preferable to separate discussion of orthogonal features into separate threads, even if they are all form- related. Makes it much easier to follow the discussion. Thanks! Carl [1] http://bitbucket.org/carljm/django-form-utils -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.