Не получается использовать две разные формы от разных моделей на одной странице. Django 2
Вызываю форму TarifStartForm. Форма открывается верно, но после нажатия кнопки submit данные сохраняются в модель TarifIndividual.
views.py
class TarifyView(CustomSuccessMessageMixin, CreateView):
model = TarifIndividual
template_name = 'tarify.html'
form_class = TarifIndividualForm
success_url = reverse_lazy('tarify')
success_msg = 'Сообщение отправлено'
def get_context_data(self, **kwargs):
kwargs['startform'] = TarifStartForm
return super().get_context_data(**kwargs)
def form_valid(self, form):
context = self.get_context_data()
self.object = form.save(commit=False)
self.object.save()
return super().form_valid(form)
forms.py
class TarifStartForm(forms.ModelForm):
class Meta:
model = TarifStart
fields = '__all__'
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs['class'] = 'form-control'
class TarifIndividualForm(forms.ModelForm):
class Meta:
model = TarifIndividual
fields = '__all__'
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs['class'] = 'form-control'
tarify.html
<!-- Всплывашка заказать Start-->
<div class="modal fade" id="order" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="staticOrder" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header my_color">
<h5 class="modal-title" id="staticOrder">Заказать Start</h5>
<button type="button" class="close cross_color" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form id="add_form_order" method="post">
{% csrf_token %}
{{startform}}
</form>
</div>
<div class="modal-footer">
<!--<button type="button" class="btn btn-secondary" data-dismiss="modal">Закрыть</button>-->
<button form="add_form_order" type="submit" class="btn btn-primary">Отправить заявку</button>
</div>
</div>
</div>
</div>
<!-- Всплывашка заказать Start END-->
<!-- Всплывашка заказать Individual-->
<div class="modal fade" id="individual" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="staticindividual" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header my_color">
<h5 class="modal-title" id="staticindividual">Заказать Individual</h5>
<button type="button" class="close cross_color" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form id="add_form_individual" method="post">
{% csrf_token %}
{{form}}
</form>
</div>
<div class="modal-footer">
<!--<button type="button" class="btn btn-secondary" data-dismiss="modal">Закрыть</button>-->
<button form="add_form_individual" type="submit" class="btn btn-primary">Отправить заявку</button>
</div>
</div>
</div>
</div>
<!-- Всплывашка заказать Individual END-->
Ответы (1 шт):
так как ты хочешь, что бы обработка обоих форм у тебя была в одном месте, то для начала
я бы добавил в каждую из форм поле prefix(https://docs.djangoproject.com/en/3.1/ref/forms/api/#prefixes-for-forms), что бы когда поступали данные к тебе ты точно мог идентифицировать из какой формы они пришли (так как могут быть пересекающиеся поля) и при частичном заполнении(только пересекающихся полей) может быть непонятно какая именно форма заполнялась.
дальше ты используешь CreateView, но все подобные View(наследники FormView) в django заточены для работы именно с одной формой. Если у тебя есть несколько форм, то тебе нужно делать обработку самостоятельно, например переопределив метод post
class TarifyView(CustomSuccessMessageMixin, CreateView):
def post(self, request, *args, **kwargs):
# тут по наличию тех или иных полей нужно определить какая именно форма обрабатывалась,
# это можно сделать добавив какое-то скрытое поле в каждую из форм или используя уникальное поле
# и тут проверять наличие этого поля в request.POST
is_start_form = request.POST.get('start-input-unique', None) is not None
if is_start_form:
form = TarifStartForm(request.POST)
else:
form = TarifIndividualForm(request.POST)
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
Либо можно создать несколько view. View где рендерится страница с формами, потом на каждую из форм создал свою CreateView, в которой бы обрабатывал свою форму. Если там много общей логики предполагается, то в итоге одна из View наследовалась бы от другой, что бы не переписывать логику.