Opened 8 years ago

Closed 4 years ago

#6632 closed New feature (invalid)

FormSet, ModelFormSet, InlineFormSet and inlines for newforms in trunk

Reported by: Petr Marhoun <petr.marhoun@…> Owned by: nobody
Component: Forms Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Design decision needed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


This ticket and patch try to add some new classes - FormSet (and BaseFormSet), ModelFormSet (and BaseModelFormSet) and InlineFormSet (and BaseInlineFormSet). It is based on the code from newforms-admin and from #6241- but there are also print methods and possibility to have a form set as a part of a form.

This patch depends on #6630 (it is necessary) and on #6631 (it is not necessary - but both patches changes the same places).

Description of FormSet

FormSet is a set of forms. There are two possibilities how to define the form - through the option "form" (default_value - None) or through all options for a class defined by the option "base_form" (default value - Form). If "form" is not None, it is used. Otherwise the form is constructed as a subclass of the option "base_form" - with inner class "Meta" with all attributes of inner class "Meta" from the form set and with all fields attributes of the form set (there are deleted from the form set). There is a restriction - the form can't have any fieldsets.

There are also another options - "deletable" (default value - False), "emptiness_test_fields" (default value - None), "emptiness_test_fields" (default value - None), "fieldset_attrs" (default value - {}), "fieldset_html_output_method" (default value - None), "fieldset_legend" (default value - None), "num_extra" (default value - 1), "orderable (default value - False), "output_type" (default value - "tr"). They are described later.

FormSet has constructor with similar arguments as Form - data, files, auto_id, prefix and initial. But if auto_id is not set, default value is not None but "form". Initial can be a list of default values for each form (or None).

Constructor create one instance of a management form (with hidden fields for counts of change and all forms) and some instances of the option "form". If there are some data, there are so many instances as management form says. Otherwise if there are initial, there are len(initial) change forms and "num_extra" add forms. Otherwise there are "num_extra" add forms and no change forms.

There are some print methods - as_table, as_ul, as_p and as_tr. They call the same print methods from each form and return join of these outputs. Method unicode calls method given by the option "output_type".

There are some utility functions - add_prefix adds order of form to prefix (otherwise all forms would have the same prefix), add_fields adds new fields if "deletable" and/or "orderable" is set.

Method full_clean validates all forms and then the form set (through the method clean). It creates new parameters of the form set - is_valid, errors, non_form_errors, cleaned_data and deleted_data. Cleaned_data is a list with all cleaned_data from all valid forms. Deleted data is a list with all form which should be deleted (because "deletable" is True and user check a special field for it.). If "orderable" is True, cleaned_data are sorted by numbers given by a user in a special field.

Add forms can be empty. It is checked by method is_empty which calls the same method of form for it - with arguments fields and exclude given by the options "emptiness_test_fields" and "emptiness_test_exclude". Empty add forms from the end are ignored and not validated and added to cleaned_data.

Methods reset changed form set as no data and no files were given. Methods is_multipart says if the form set needs to be multipart-encrypted.

Description of ModelFormSet

ModelFormSet is a set of model forms. The form is defined by the same way as in FormSet - but all options from ModelForm can be used (and this class is default value for option "base_form").

Constructor have not argument initial but queryset and possible kwargs for the queryset. Default value for queryset is given by the method queryset - its default value are all objects from the model given by the model from the option "form".

Method add_forms adds also hidden field for primary key from change forms. And there is new method save which saves (or deletes) objects given by the cleaned_data (or deletable_data). This method uses utility functions save_new, save_instance, save_existing_objects and save_new_objects.

Description of InlineFormSet

InlineFormSet is a ModelFormSet for model with ForeignKey to another model. Default values for some options are changed - "deletable" is True, "num_extra" is 3. There are also new options - "parent_model" (default value None, but it has to be set) and "fk_name" (optional - for situation when there is more than one ForeignKey to the parent model).

Constructor have no argument queryset but instance (instance of parent model). Method get_queryset filters results and returns only such objects where the instance of parent model is given by the argument instance.

Important changes in BaseForm

There are new options - "inlines" and "output type". The option "inlines" is a list of form sets. But it is also possible to have in the option "fieldsets" some items which are not real fieldsets, but a form set. It is not possible use the options "inlines" and "fieldsets" in the same time.

All methods are changed to generate correct html and to do the right thing in other situations (for example in validation). Constructor have a new argument inlines - with instances of form sets given by the options.

Method unicode is changed to call method given by the option "output_type". It is for situations when form is part of an form set and it is printed only indirectly through the methods from another (parent) form. There is also a new method as_tr - it is something as tabular inlines in admin.

There is a new utility method inline_html_output. It generates fieldset html for an inline - it uses options from the form set "fieldset_attrs", and "fieldset_legend". This method could be replaced by the option "fieldset_html_output_method" from the form set.

There are new method is_empty and reset - their purpose is the same as in the form sets. Method is_empty calls are widget (arguments fields and exclude can restrict them) and asks them if they are empty.

Important changes in ModelBaseForm

Its constructor creates inlines - all are based on the argument instance. And these inlines are saved if form is valid.

Important changes in Widget

There is a new method is_empty - it is called by the forms to check this property.

There is a new method for_tr which is used by the method html_output of BaseForm.

Attachments (5)

02-newforms-inlines.diff (38.9 KB) - added by Petr Marhoun <petr.marhoun@…> 8 years ago.
02-newforms-inlines.2.diff (38.7 KB) - added by Petr Marhoun <petr.marhoun@…> 8 years ago.
02-forms-inlines.diff (36.6 KB) - added by Petr Marhoun <petr.marhoun@…> 7 years ago.
02-forms-inlines.2.diff (35.9 KB) - added by Petr Marhoun <petr.marhoun@…> 7 years ago.
01-inlines.diff (14.8 KB) - added by Petr Marhoun <petr.marhoun@…> 7 years ago.

Download all attachments as: .zip

Change History (14)

Changed 8 years ago by Petr Marhoun <petr.marhoun@…>

comment:1 Changed 8 years ago by fivethreeo

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

found a error at line 318, name should be

Changed 8 years ago by Petr Marhoun <petr.marhoun@…>

comment:2 Changed 8 years ago by Petr Marhoun <petr.marhoun@…>

  • Patch is based on the new patch from #6631 and depends on it.
  • Some bugs in inlines are fixed so inlines really works as part of a form now.
  • Caching of querysets in inner form is solved - but the solution is ugly and has to be improved (I will think about it).
  • Bug from the previous comment fixed (thanks).
  • Option fieldset_html_output_method is removed because it is to complex and could be replaced be BaseForm._inline_html_output.
  • Some options are renamed to be shorter.
  • Complete list of options - form, base_form, deletable, is_empty_fields, is_empty_exclude, fieldset_attrs, fieldset_legend, num_extra, orderable, output_type (and all from inner form). (I am sure that native speakers could find better names.)

comment:3 Changed 8 years ago by jkocherhans

  • Resolution set to invalid
  • Status changed from new to closed

This will probably only happen when the newforms-admin branch is merged to trunk. None of these classes has a public API yet.

Changed 7 years ago by Petr Marhoun <petr.marhoun@…>

comment:4 Changed 7 years ago by Petr Marhoun <petr.marhoun@…>

  • Resolution invalid deleted
  • Status changed from closed to reopened

Newforms-admin was merged and I changed patch to be compatible with the new trunk. But it is very speculative and rough. It will depends on resolution to #6630.

comment:5 Changed 7 years ago by ericholscher

  • milestone set to post-1.0
  • Triage Stage changed from Unreviewed to Design decision needed

Changed 7 years ago by Petr Marhoun <petr.marhoun@…>

Changed 7 years ago by Petr Marhoun <petr.marhoun@…>

comment:6 Changed 7 years ago by anonymous

  • milestone post-1.0 deleted

Milestone post-1.0 deleted

comment:7 Changed 5 years ago by julien

  • Type set to New feature

comment:8 Changed 5 years ago by julien

  • Severity set to Normal

comment:9 Changed 4 years ago by carljm

  • Easy pickings unset
  • Resolution set to invalid
  • Status changed from reopened to closed
  • UI/UX unset

Some of this we have already (formsets) and the remainder need to be filed as separate, independent tickets. This is way too much to cram into one ticket.

Note: See TracTickets for help on using tickets.
Back to Top