На этот вопрос уже был дан ответ, например, здесь: Правильный способ обработки нескольких форм на одной странице в Django
Перед тем, как он будет помечен как дубликат. Я попытаюсь объяснить, почему он отличается.
У меня есть три таблицы: Project
, ProjectUser
и User
. ProjectUser
- это таблица соединений, указывающая, каким пользователям принадлежит какой проект.
Я пытаюсь создать представление, которое позволяет пользователям обновлять детали проекта (например, имя проекта), а также добавлять пользователей в проект (что обозначено раскрывающимся списком, в котором все доступные пользователи отображаются как стандартные для моделей с внешними ключами в админ-панели django). Все работает нормально, пока я не пытаюсь передать идентификатор из представлений в класс и отправить.
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"]
Визуализация форм работает просто отлично с нужным набором запросов, но когда я пытаюсь отправить вторую форму (добавив пользователя в ProjectUserForm, я просто получаю ошибку
__init__() missing 1 required positional argument: 'queryset'
. Есть идеи о том, как решить эту проблему? Возможно, я делаю это намного сложнее, чем следовало бы
Я также добавил скриншот, если это поможет: https://imgur.com/a/uqu0UeB