I am working on my first Django Project.
I have a Many-to-Many Relation between two models: User and Project. While Updating a Project, I want to show form with Add New members and remove Existing members field with correct Choices based on current Project Users.
Here is what I tried so far:
- Get the Current Project from URL
- Pass the current Project to Model Form
- In Form, run Custom queryset.
Problem: Not Displaying result of Query Set.
In views.py
class UpdateProject(LogInRequiredMixin, UpdateView):
""" Class to Edit Project.
"""
form_class = ProjectUpdateForm
template_name = 'project/create.html'
def get_object(self):
self.project_instance = models.Project.objects.get(pk=self.kwargs['project'])
return self.project_instance
def get_form_kwargs(self):
kwargs = super(UpdateProject, self).get_form_kwargs()
kwargs.update({'project': self.project_instance})
return kwargs
For forms ProjectUpDateForm
class ProjectUpdateForm(forms.ModelForm):
""" Form to update Project Field. """
add_member = forms.CharField(label="Add New Members", widget=forms.CheckboxSelectMultiple)
del_member = forms.CharField(label="Remove Members", widget=forms.CheckboxSelectMultiple)
def __init__(self, *args, **kwargs):
self.project = kwargs.pop('project')
super(ProjectUpdateForm, self).__init__(*args, **kwargs)
print MyUser.objects.exclude(pk__in=self.project.members.all())
print MyUser.objects.filter(pk__in=self.project.members.all())
self.fields['add_member'].queryset = MyUser.objects.exclude(pk__in=self.project.members.all())
self.fields['del_member'].queryset = MyUser.objects.filter(pk__in=self.project.members.all())
# Rest of Class Logic
Print Statements are working and returning correct result, however I am unable to view the results in app. It is displaying blank.
Also, I want to know is their easier way to achieve the same? (Seems to me that I shouldn't have to pass project explicitly? )
As far as I could find out, this solves the problem
When adding Many-To-Many field explicitly in Model Form, and you expect Multiple response, the module used should be ModelMultipleChoiceField
Also, since we are over-riding init method, and have a queryset in it, the best place to define it is inside init.
Final Form Code:
And this should do it!
May be useful to someone
In case, we already have defined field in our model, we don't need to completely over-write it in init (if query requires passed parameters)
We can define it queryset in init by self.fields['field_name'].queryset = logic
And add widget in Meta class.
PS: I am still searching for easier way to access current object rather than being explicitly passed by View though!