Django Passing Custom Form Parameters to Formset Django Passing Custom Form Parameters to Formset django django

Django Passing Custom Form Parameters to Formset


I would use functools.partial and functools.wraps:

from functools import partial, wrapsfrom django.forms.formsets import formset_factoryServiceFormSet = 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).


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


I would build the form class dynamically in a function, so that it has access to the affiliate via closure:

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

As a bonus, you don't have to rewrite the queryset in the option field. The downside is that subclassing is a little funky. (Any subclass has to be made in a similar way.)

edit:

In response to a comment, you can call this function about any place you would use the class name:

def view(request):    affiliate = get_object_or_404(id=request.GET.get('id'))    formset_cls = formset_factory(make_service_form(affiliate))    formset = formset_cls(request.POST)    ...