Напоминает ответ @james (у меня была аналогичная отправная точка), но ему не нужно получать имя формы через данные POST. Вместо этого он использует автоматически сгенерированные префиксы, чтобы определить, какие формы получили данные POST, назначить данные, проверить эти формы и, наконец, отправить их соответствующему методу form_valid. Если есть только одна связанная форма, он отправляет эту единственную форму, иначе он отправляет {"name": bound_form_instance}
словарь.
Он совместим с forms.Form
или другими классами, ведущими себя к форме, которым может быть назначен префикс (например, наборы форм django), но еще не создан вариант ModelForm, хотя вы можете использовать форму модели с этим представлением (см. редактирование ниже) . Он может обрабатывать формы в разных тегах, несколько форм в одном теге или их комбинацию.
Код размещен на github (https://github.com/AlexECX/django_MultiFormView). Есть некоторые рекомендации по использованию и небольшая демонстрация, охватывающая некоторые варианты использования. Цель состояла в том, чтобы создать класс, максимально похожий на FormView.
Вот пример с простым вариантом использования:
views.py
class MultipleFormsDemoView(MultiFormView):
template_name = "app_name/demo.html"
initials = {
"contactform": {"message": "some initial data"}
}
form_classes = [
ContactForm,
("better_name", SubscriptionForm),
]
# The order is important! and you need to provide an
# url for every form_class.
success_urls = [
reverse_lazy("app_name:contact_view"),
reverse_lazy("app_name:subcribe_view"),
]
# Or, if it is the same url:
#success_url = reverse_lazy("app_name:some_view")
def get_contactform_initial(self, form_name):
initial = super().get_initial(form_name)
# Some logic here? I just wanted to show it could be done,
# initial data is assigned automatically from self.initials anyway
return initial
def contactform_form_valid(self, form):
title = form.cleaned_data.get('title')
print(title)
return super().form_valid(form)
def better_name_form_valid(self, form):
email = form.cleaned_data.get('email')
print(email)
if "Somebody once told me the world" is "gonna roll me":
return super().form_valid(form)
else:
return HttpResponse("Somebody once told me the world is gonna roll me")
template.html
{% extends "base.html" %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ forms.better_name }}
<input type="submit" value="Subscribe">
</form>
<form method="post">
{% csrf_token %}
{{ forms.contactform }}
<input type="submit" value="Send">
</form>
{% endblock content %}
EDIT — о ModelForms
Хорошо, изучив ModelFormView, я понял, что создать MultiModelFormView будет не так просто, мне, вероятно, также потребуется переписать SingleObjectMixin. В то же время вы можете использовать ModelForm, если вы добавите аргумент ключевого слова «экземпляр» с экземпляром модели.
def get_bookform_form_kwargs(self, form_name):
kwargs = super().get_form_kwargs(form_name)
kwargs['instance'] = Book.objects.get(title="I'm Batman")
return kwargs
person
Alexandre Cox
schedule
26.08.2018