Skip to content

Instantly share code, notes, and snippets.

@andrefsp
Last active March 1, 2021 22:22
Show Gist options
  • Save andrefsp/5115772 to your computer and use it in GitHub Desktop.
Save andrefsp/5115772 to your computer and use it in GitHub Desktop.
Simple way to inject custom parameters on a Django formset without using django.utils.functional.curry()
"""
Simple example on how to inject a custom user parameters onto a formset
and its forms.
curry(): https://github.com/django/django/blob/1.4.3/django/utils/functional.py#L9
Another answer on:
http://stackoverflow.com/questions/622982/django-passing-custom-form-parameters-to-formset
"""
class BaseAddToBasketForm(forms.Form):
product = forms.ModelChoiceField(queryset=Product.objects.none())
quantity = forms.IntegerField(initial=0)
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user') # user was passed to a single form
        super(BaseAddToBasketForm, self).__init__(*args, **kwargs)
# create a base Formset class
BaseAddToBasketFormSet = formset_factory(BaseAddToBasketForm)  
class AddToBasketFormSet(BaseAddToBasketFormSet): # sub class it
    def __init__(self, *args, **kwargs):
#  create a user attribute and take it out from kwargs
# so it doesn't messes up with the other formset kwargs
        self.user = kwargs.pop('user')
        super(AddToBasketFormSet, self).__init__(*args, **kwargs)   
    def _construct_form(self, *args, **kwargs):
# inject user in each form on the formset
        kwargs['user'] = self.user       
        return super(AddToBasketFormSet, self)._construct_form(*args, **kwargs)
# Instantiate a form for user 'blabla':
AddToBasketFormSet(user="blabla")  
@andrefsp
Copy link
Author

True. The underlying issue here is that simply injecting a kwarg on a Formset will mess the order in which arguments get's passed to the constructor. A formset expects the first argument to be data.
In my opinion using kwargs.pop() its a good way to don't mess up with the kwargs order and doesn't bring the level of complexity curry() does.

@eagle-r
Copy link

eagle-r commented Sep 18, 2015

One issue that I encountered with this approach is that it doesn't work for the empty_form

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment