Passing arguments to ModelForm through FormSet

django, django-forms

Solution

It should be possible to subclass `BaseModelFormset` so that the user is passed to each form when it is constructed. However, that's quite tricky.

A simpler technique is to define a function that creates a model form for a given user, and dynamically create the model form class in the view.

def create_form(user):
    """Returns a new model form which uses the correct queryset for user"""

    class AddUpdateEntryForm(forms.ModelForm):

        class Meta:
            model = Zeit
            exclude = ('mitarbeiter', 'user_updated')

        def __init__(self, *args, **kwargs):
            super(AddUpdateEntryForm, self).__init__(*args, **kwargs)
            self.fields['projekt'].queryset = Projekt.objects.filter(firma=Mitarbeiter.objects.get(user_id=user).firma_id)

    return AddUpdateEntryForm

The closure of `user` in the function means that you can set the queryset correctly. Note that the `__init__` method takes the same arguments as its parent class, so we no longer have any problems when we use `modelformset_factory` in the view.

AddUpdateEntryForm = create_form(user)
AddEntryFormSet = modelformset_factory(model=Zeit, form=AddUpdateEntryForm)

Problem

I'm kinda new to Formsets and I'm stuck at a problem. I use a Modelform to allow the creation of a new object. ``` class AddUpdateEntryForm(forms.ModelForm): class Meta: model = Zeit exclude = ('mitarbeiter', 'user_updated') def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') super(AddUpdateEntryForm, self).__init__(*args, **kwargs) self.fields['projekt'].queryset = Projekt.objects.filter(firma=Mitarbeiter.objects.get(user_id=self.user).firma_id) ``` That form gets it's arguments from the view: ``` form = AddUpdateEntryForm(user=entry_user, initial=initial) ``` Now, I want to display multiple instances of that form on a single page. I use: ``` forms.py: AddEntryFormSet = formset_factory(form=AddUpdateEntryForm) ``` and ``` views.py: formset = AddEntryFormSet(initial=initial) ``` which works fine, but only when I comment out the "self.user...." and "self.fields...." lines from ModelForm Class. I tried several ways of passing the argument from the call inside the view to the ModelForm. Is there a proper way to do this? Thanks in advance Conrad

Original source