This question have been answered before, e.g here: Proper way to handle multiple forms on one page in Django
So before it gets marked as a duplicate. I'll try to explain why its different.
I've got three tables, Project
, ProjectUser
and User
. ProjectUser
is a join table to indicate what users belongs to what project.
I'm trying to create a view that lets users update project details (e.g. name of project), and also add users to the project (which is indicated by a dropdown that shows all available users like the standard one for models with foreign keys in the django admin panel). All works fine until I'm trying to pass an id from the views to the formclass and submit.
views.py
class ProjectUpdateView(UpdateView):
form_class = ProjectUpdateForm
second_form_class = ProjectUserAddForm
template_name = 'projects/project_edit.html'
success_url = reverse_lazy('projects:list')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
id_ = self.kwargs.get("id")
project = Project.objects.get(id=id_)
if 'form' not in context:
context['form'] = self.form_class()
if 'form2' not in context:
team = Organization.objects.get(id=project.organization_id)
context['form2'] = self.second_form_class(queryset=team) # <-- here is where I wish to pass a queryset, which fails when trying to submit form2.
context['project_users'] = ProjectUser.objects.filter(project__id=project.id).select_related("project")
context['team'] = Organization.objects.get(id=project.organization_id)
return context
def get_object(self):
id_ = self.kwargs.get("id")
return get_object_or_404(Project, id=id_)
def form_invalid(self, **kwargs):
return self.render_to_response(self.get_context_data(**kwargs))
def form_valid(self, form):
project_id = self.kwargs.get("id")
if self.request.POST.get("form2") == 'Add':
ProjectUser.objects.create(user_id=self.request.POST.get("user"), project_id=project_id)
form.save()
success_url = reverse("projects:edit", args=(project_id,))
return HttpResponseRedirect(success_url)
def post(self, request, *args, **kwargs):
# get the user instance
self.object = self.get_object()
# determine which form is being submitted
# uses the name of the form's submit button
if 'form' in request.POST:
# get the primary form
form_class = self.get_form_class()
form_name = 'form'
else:
# get the secondary form
form_class = self.second_form_class
form_name = 'form2'
# get the form
form = self.get_form(form_class)
# validate
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(**{form_name: form})
projects_edit.html
<form action="{% url 'projects:edit' project.id %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form.name|as_crispy_field}}
<input name="form" value="Update" type="submit"></input>
</form>
<form action="{% url 'projects:edit' project.id %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form2.user}}
<input name="form2" value="Add" type="submit"></input>
</form>
forms.py
class ProjectUpdateForm(ModelForm):
class Meta:
model = Project
fields = ["name"]
class ProjectUserAddForm(ModelForm):
def __init__(self, queryset, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['user'].queryset = User.objects.filter(organizations_organizationuser__organization__id=queryset.id) # here is where I wish to pass the id of the queryset from the form class
class Meta:
model = ProjectUser
fields = ["user"]
Rendering the forms works just fine with the desired queryset, but when I try to submit the second form (adding a user to the ProjectUserForm, I just get a
__init__() missing 1 required positional argument: 'queryset'
error.
Any ideas on how to solve this? Perhaps I'm making it way more complicated than it should
I have also added a screenshot if it helps: https://i.stack.imgur.com/gmO8s.jpg