Opened 13 years ago

Closed 10 years ago

Last modified 10 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
Pull Requests:4757 merged

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

Change History (13)

by tevans, 13 years ago

Patch implementing features described in ticket

comment:1 by tevans, 13 years ago

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

comment:2 by tevans, 13 years ago

Needs documentation: set
Needs tests: set

in reply to:  1 comment:3 by Łukasz Rekucki, 13 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, 13 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, 13 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, 13 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, 13 years ago

Oops that was me.

comment:8 by Sergei Maertens, 10 years ago

Owner: changed from nobody to Sergei Maertens
Status: newassigned

comment:9 by Sergei Maertens, 10 years ago

I'll have a go at this

comment:10 by Sergei Maertens, 10 years ago

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

comment:11 by Sergei Maertens <sergei@…>, 10 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@…>, 10 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