One of the initial problems I encountered with developing Django for the first time was how to pass object information to a formset so I could filter out a choices field based on the current user. There are two methods you need to override to accomplish this task, one is get_form_kwargs in the generic view CreateView, and the other is the __init__ method in the Django formset.
To kick this off, I will be using an example from a previous Django project I have developed. So let’s begin. First when it comes to passing object information in order to filter a form’s ChoiceField one must first override the get_form_kwargs in a generic view, such as the CreateSiteRequirementView seen here(views.py):
Let’s examine what’s going on here:
1.) On line 647, I am using self.kwargs[‘pk’] to grab the primary key from the url of the current view.
2.) On lines 648-649, I’m grabbing the site ID via the foreign key provided via self.kwargs[‘pk’] as well as the user_id attribute from the site object.
3.) On Line 650, I’m calling super to allow me store keyword arguments into the kwargs variable.
4.) On line 651, I’m calling the update method of the kwargs object so I can pass the current user’s information to the formset via kwargs.
Now on the formset(forms.py) we have to override the __init__ method so we can use the kwargs being passed to the formset. As you can see here:
So what’s going here? Let’s see:
1.) We are overriding the __init__ method so we can retrieve the objection information being passed to it via get_form_kwargs. On line 104, notice the user=None argument, which is the same user object being passed to the form via get_form_kwargs.
2.) On line 106, we are verifying whether a user is actually being passed to the form.
3.) On line 107 we are now using the passed user variable to get the requirements for that user only.
4.) And lastly, on line 108 we use a list comprehension to iterate through the requirements objects to assign the primary key and the object name to the choices field via self.fields[‘requirement’].choices.
And that’s it. If you have any questions/comments/concerns please feel free to comment. Thanks.