Django Passing Custom Form Parameters to Formset


Question

This was fixed in Django 1.9 with form_kwargs.

I have a Django Form that looks like this:

class ServiceForm(forms.Form):
    option = forms.ModelChoiceField(queryset=ServiceOption.objects.none())
    rate = forms.DecimalField(widget=custom_widgets.SmallField())
    units = forms.IntegerField(min_value=1, widget=custom_widgets.SmallField())

    def __init__(self, *args, **kwargs):
        affiliate = kwargs.pop('affiliate')
        super(ServiceForm, self).__init__(*args, **kwargs)
        self.fields["option"].queryset = ServiceOption.objects.filter(affiliate=affiliate)

I call this form with something like this:

form = ServiceForm(affiliate=request.affiliate)

Where request.affiliate is the logged in user. This works as intended.

My problem is that I now want to turn this single form into a formset. What I can't figure out is how I can pass the affiliate information to the individual forms when creating the formset. According to the docs to make a formset out of this I need to do something like this:

ServiceFormSet = forms.formsets.formset_factory(ServiceForm, extra=3)

And then I need to create it like this:

formset = ServiceFormSet()

Now how can I pass affiliate=request.affiliate to the individual forms this way?

1
141
3/31/2016 4:24:20 PM

Accepted Answer

I would use functools.partial and functools.wraps:

from functools import partial, wraps
from django.forms.formsets import formset_factory

ServiceFormSet = formset_factory(wraps(ServiceForm)(partial(ServiceForm, affiliate=request.affiliate)), extra=3)

I think this is the cleanest approach, and doesn't affect ServiceForm in any way (i.e. by making it difficult to subclass).

104
1/7/2015 4:49:11 PM

Official Document Way

Django 2.0:

ArticleFormSet = formset_factory(MyArticleForm)
formset = ArticleFormSet(form_kwargs={'user': request.user})

https://docs.djangoproject.com/en/2.0/topics/forms/formsets/#passing-custom-parameters-to-formset-forms


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon