Opened 7 years ago

Last modified 5 months ago

#10403 assigned New feature

provide declarative syntax to define FormSets - including ModelFormSet and InlineFormSet

Reported by: Koen Biermans <koen.biermans@…> Owned by: auvipy
Component: Forms Version: master
Severity: Normal Keywords: formset modelformset inlineformset
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: yes
Needs tests: yes Patch needs improvement: yes
Easy pickings: no UI/UX: no


Provide a declarative mechanism to define modelformsets or inlineformsets.

The attached patch allows definitions like this:

class AuthorForm(forms.ModelForm):
    class Meta:
        model = Author

class DeclarativeAuthorFormSet(forms.models.ModelFormSet):
    form = AuthorForm
    model = Author
    extra = 3


class BookForm(forms.ModelForm):
    class Meta:
        model = Book

class DeclarativeAuthorBooksFormSet(forms.models.InlineFormSet):
    model = Book
    form = BookForm
    parent = 'author'

An advantage is that the defined form is directly used as the form class in the formset, not as a base class for a new form class (what inlineformset_factory does). This way specific field definitions and other customisations in the form work like they should so you don't need to redefine things in init().

Attachments (2)

declarativeformsets.diff (15.9 KB) - added by Koen Biermans <koen.biermans@…> 7 years ago.
patch to provide declarative syntax for modelformset and inlineformset
django-10403.diff (27.7 KB) - added by bpeschier 4 years ago.

Download all attachments as: .zip

Change History (9)

Changed 7 years ago by Koen Biermans <koen.biermans@…>

patch to provide declarative syntax for modelformset and inlineformset

comment:1 Changed 7 years ago by jacob

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed

comment:2 Changed 4 years ago by SmileyChris

  • Severity set to Normal
  • Type set to New feature

comment:3 Changed 4 years ago by melinath

  • Easy pickings unset
  • Keywords formset added
  • Needs documentation set
  • Needs tests set
  • Patch needs improvement set
  • Summary changed from provide declarative syntax to define ModelFormSet and InlineFormSet to provide declarative syntax to define FormSets - including ModelFormSet and InlineFormSet
  • UI/UX unset

Closed #16289 as a duplicate - it proposed essentially the same thing as this ticket, but included all FormSets, not just ModelFormSets. Hence I'm widening the scope of this a little. (Also marking as needs tests since the tests in the patch are doctests.)

comment:4 Changed 4 years ago by bpeschier

Ok, so I missed this one O:)

I disagree with the implementation in the patch, no MetaClass is needed and just simple additions to the class definitions to make it work, maybe with the exception of InlineFormSet. Will attach a patch later on.

Changed 4 years ago by bpeschier

comment:5 Changed 3 years ago by rasca

Adding a comment from #16289:

This would be very useful for a nicer implementation of the formset derived cbv #16256.

The BaseInlineFormSet? is the only tricky one with the _get_foreign_key() and the max_num override when fk.unique=True .

I'd also move the defaults (e.g. extra=3) to the BaseFormSet? and make the factories only pass dict keys whose value isn't None to type().

comment:6 Changed 2 years ago by carljm

  • Triage Stage changed from Design decision needed to Accepted

The current factory-function implementation of formsets is unnecessarily confusing to new users, and unlike anything else in Django. It can also cause obscure issues with things that should "just work" (see e.g. It's ironic that we provide declarative syntax for things like models and forms where it requires metaclass magic, but in the case of formsets where a declarative syntax is a simple matter of normal Python subclassing, we don't :-)

Haven't reviewed the latest patch in depth, but the broad strokes look correct to me.

comment:7 Changed 5 months ago by auvipy

  • Owner changed from nobody to auvipy
  • Status changed from new to assigned
Note: See TracTickets for help on using tickets.
Back to Top