Opened 12 years ago

Closed 9 years ago

Last modified 9 years ago

#18166 closed New feature (fixed)

Allow the formset class to contribute kwargs to form instances

Reported by: tevans Owned by: Sergei Maertens
Component: Forms Version: dev
Severity: Normal Keywords: forms formset kwargs
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Łukasz Rekucki)

When we use a formset, each form is instantiated by the method BaseFormSet._construct_forms(), which is called from BaseFormSet.__init__()

_construct_forms() allows for additional kwargs to be passed through to the individual form constructor, but BaseFormSet.__init__() does not provide any mechanism for kwargs to be passed through to the _construct_forms() call.

Also, we may not be able to supply a static unchanging list of kwargs that should be supplied to each form constructor - the kwargs we want to pass may depend upon the specific instance of the form being instantiated.

I propose the following changes:

Add a form_kwargs argument to BaseFormSet.__init__(). This would be stored on self, and consumed in BaseFormSet._construct_forms()

Add a method, BaseFormSet._kwargs_for_form(self, i). This method would be called for each form instantiated, passing the index of the form within the formset. The return value of this method would be merged with the form_kwargs supplied in BaseFormSet.__init__() and used to instantiate the form.

With these changes, a user could add additional constructor arguments to all forms by passing in form_kwargs to the formset constructor, and could add additional constructor arguments to specific forms by implementing _kwargs_for_form on a derived BaseFormSet class.

(I found it strange, when BaseFormSet was written, it was clearly intended to be able to pass kwargs to the forms - _construct_form() allows for it, there just is not the plumbing to do so. I worked around this by redefining - copy/pasting - the _construct_forms() method in my derived BaseFormSet class)

Patch doesn't have tests or doc changes, will add if this idea gets traction.

Cheers

Tom

Attachments (1)

django-formset-form-kwargs.diff (2.1 KB ) - added by tevans 12 years ago.
Patch implementing features described in ticket

Download all attachments as: .zip

Change History (13)

by tevans, 12 years ago

Patch implementing features described in ticket

comment:1 by tevans, 12 years ago

Hmm, wiki markup that turns __init__ into init is less than useful for Python discussion :/

comment:2 by tevans, 12 years ago

Needs documentation: set
Needs tests: set

in reply to:  1 comment:3 by Łukasz Rekucki, 12 years ago

Description: modified (diff)

Replying to tevans:

Hmm, wiki markup that turns __init__ into init is less than useful for Python discussion :/

You can use formatting: {{{ __init__ }}} will show as __init__. There's both live preview and a preview button.

comment:4 by Anssi Kääriäinen, 12 years ago

Just as an idea: how about defining a new method:

def get_single_form(self, i, defaults):
    """
    Override me to have total control over the single forms.
    """
    return self.form(**defaults)

and use that instead of self.form() in the _construct_form() method. This would be more powerful and easier to implement.

in reply to:  4 comment:5 by tevans, 12 years ago

Replying to akaariai:

Just as an idea: how about defining a new method:

def get_single_form(self, i, defaults):
    """
    Override me to have total control over the single forms.
    """
    return self.form(**defaults)

and use that instead of self.form() in the _construct_form() method. This would be more powerful and easier to implement.

Yes, I like that. I would like to also keep the idea of being able to contribute to a form's kwargs without defining a BaseFormSet subclass, eg by passing them to BaseFormSet.__init__.

I should get some time this w/e to re-roll the patch.

comment:6 by anonymous, 12 years ago

Patch needs improvement: set
Triage Stage: UnreviewedAccepted

Agreed, a method for implementing this is a good idea, but please let's skip the redundant 'simple' prefix, just call it get_form.

comment:7 by Jannis Leidel, 12 years ago

Oops that was me.

comment:8 by Sergei Maertens, 9 years ago

Owner: changed from nobody to Sergei Maertens
Status: newassigned

comment:9 by Sergei Maertens, 9 years ago

I'll have a go at this

comment:10 by Sergei Maertens, 9 years ago

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset

comment:11 by Sergei Maertens <sergei@…>, 9 years ago

Resolution: fixed
Status: assignedclosed

In 238e2ac3:

Fixed #18166 -- Added form_kwargs support to formsets.

By specifying form_kwargs when instantiating the formset, or overriding
the get_form_kwargs method on a formset class, you can pass extra
keyword arguments to the underlying Form instances.

Includes tests and documentation update.

comment:12 by Russell Keith-Magee <russell@…>, 9 years ago

In fe21fb81:

Merge pull request #4757 from sergei-maertens/ticket_18166

Fixed #18166 -- Added ability to pass kwargs to the form constructor in a formset.

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