Найти - Пользователи
Полная версия: Обработка нескольких форм разл. классов одним контроллером
Начало » Django » Обработка нескольких форм разл. классов одним контроллером
1 2
Alex.py
Здравствуйте!

На одной странице отрендерены несколько форм, различных классов, образованных от forms.Form.


 <form action="{% url 'app:route' parameter %}" method="post">
{% for q_form in q_forms %}
  {% csrf_token %}
 
 <div class="row form-row spacer">
  {{ q_form.name.value }}
  <div class="input-group">{{ q_form.ans }}</div>
 </div>
{% endfor %}
<button type="submit">ПРИНЯТЬ</button>
</form>

Они все передаются одним списком в контексте на вышепоказанную страницу и классы в списке неупорядочены, таким образом, что сначала бы шли формы одного класса, а потом другого.

После заполнения, нужно произвести обработку всех форм одним контроллером. То есть, если бы я нажал на кн. “ПРИНЯТЬ” формы бы отправились все в положенных им блоках. Сейчас после их заполнения значения, естественно, отправляются в одном списке.

Если использовать formsets то там условие такое, что нужно при его инициализации, задать класс форм, которые будут принадлежать formset.

Поэтому какие приёмы использовать в таком случае я не знаю. Что приходит в голову, так это какой-то jquery написать, чтобы он по нажатию кнопки все формы отправил, но может, это можно сделать иначе, не прибегая к средствам jquery, допустим, как-то разметить html?

FishHook
Фактически, вам надо, чтобы по имени конкретного контрола формы, можно было понять, какой форме он принадлежит. То есть надо каким-то образом поместить информацию о форме в аттрибут name. Я бы на вашем месте долго не думал, и использовал префиксы.

https://docs.djangoproject.com/en/3.1/ref/forms/api/#prefixes-for-forms
Alex.py
Немного непонятно как это правильно сделать…

Таким образом поместив в один тег “form” несколько форм трёх классов, назначив им prefix из, допустим {'classForm1', ‘classForm2’, ‘classForm3’}, мы добиваемся их обработки одним контроллером, используя для этого namespace по имени prefix?


appname/classForm1_urls.py:

 from django.urls import re_path
from . import views
app_name = 'appname'
urlpatterns = [
    re_path(r'^somepath/(?P<parameter>[-+]?\d+)/$', views.saving_qforms, name='route'),
]

appname/classForm2_urls.py:

 from django.urls import re_path
from . import views
app_name = 'appname'
urlpatterns = [
    re_path(r'^somepath/(?P<parameter>[-+]?\d+)/$', views.saving_qforms, name='route'),
]

appname/classForm3_urls.py:

 from django.urls import re_path
from . import views
app_name = 'appname'
urlpatterns = [
    re_path(r'^somepath/(?P<parameter>[-+]?\d+)/$', views.saving_qforms, name='route'),
]

urls.py на уровне приложения appname:

 from django.urls import path, include
urlpatterns = [
    path('somepath/', include('classForm1_urls', namespace='classForm1')),
    path('somepath/', include('classForm2_urls', namespace='classForm2')),
    path('somepath/', include('classForm3_urls', namespace='classForm3')),
]


а в шаблоне так:

 <form action="{% url 'appname:route' parameter %}" method="post">
{% for q_form in q_forms %}
  {% csrf_token %}
 
 <div class="row form-row spacer" name="{{ q_form.prefix }}">
  {{ q_form.name.value }}
  <div class="input-group">{{ q_form.ans }}</div>
 </div>
{% endfor %}
<button type="submit">ПРИНЯТЬ</button>
</form>


в контроллере не знаю как нужно обрабатывать, поскольку для каждого класса, форм может быть несколько. Но думаю, что они будут все в запросе идти отдельно, а не скопом, так что все значения от всех форм в одном списке соберутся.
FishHook
Alex.py
мы добиваемся их обработки одним контроллером
Вам конкретно что надо, чтобы поля нескольких форм отправлялись одним запросом, или чтобы они отправлялись в разных рапросах, но обрабатывались одной вьюшкой?
Alex.py
FishHook
или чтобы они отправлялись в разных рапросах, но обрабатывались одной вьюшкой?
Да, я хочу каждую форму обработать отдельно, ибо данные каждой формы это основа одного создаваемого экземпляра модели. Но отправка всех форм клиентом по нажатию одной кнопки, отправляя тем самым все заполненные формы на один контроллер. Это возможно?

На одной странице может быть сколь угодно форм 3-х классов, все они неупорядоченно следуют. Вот клиент заполняет их , потом жмёт “принять”.
FishHook
Камрад, я нифига не понимаю, чего ты хочешь.
Alex.py
отправляя тем самым все заполненные формы
Ок, то есть все данные со всех форм уходят одним запросом.
Alex.py
Да, я хочу каждую форму обработать отдельно
Но при этом они должны обрабатываться как-то “отдельно”, что бы это не значило. Это как понять то?
Если вы оправляете кучу данных одним реквестом, то какое-то одно представление примет этот реквест. Далее вам надо на основаннии реквеста инстанциировать N форм. Ну сделайте это в цикле по списку форм. Для каждой формы напишите отдельный обработчик - класс или функцию, как больше нравится. Вот и будет вам “отдельно”.
Alex.py
FishHook
Ок, то есть все данные со всех форм уходят одним запросом.

Ну да, я предполагаю, что все формы придут в контроллер как <QueryDict: {'form1':, ‘form2’:}> и там каждую проверять на is_valid() is True и т.д.

Если назначить каждой форме свой уникальный id и отправить их js по нажатию кн. “ПРИНЯТЬ”. Как я это представляю, насколько это правильно, в js в цикле, каждую форму отправить, перебирая id's.



 <form action="/briefing/results/2/" id="1" method="post">
	<div class="row form-row spacer">
		<p>Название</p>
		<div class="input-group"><ul id="id_Variant_Ans-ans">
    <li><label for="id_Variant_Ans-ans_0"><input type="checkbox" name="Variant_Ans-ans" value="97" id="id_Variant_Ans-ans_0">
 вариант 1</label>
</li>
    <li><label for="id_Variant_Ans-ans_1"><input type="checkbox" name="Variant_Ans-ans" value="98" id="id_Variant_Ans-ans_1">
 вариант 2</label>
</li>
</ul></div>
	 </div>
	 <input type="submit" style="display:none">
</form>
<form action="/briefing/results/2/" id="2" method="post">
	<input type="hidden" name="csrfmiddlewaretoken" value="QblveCfhWakAm1xeSU5srBZia5hKNSv8LEgNOR7sJVdioPM7QsgD2uDQn6A3hwbp">
	<div class="row form-row spacer">
		<p>Название2[quote=FishHook]Ок, то есть все данные со всех форм уходят одним запросом.[/quote]
</p>
		
		<div class="input-group"><textarea name="Text_Ans-ans" cols="40" rows="10" required="" id="id_Text_Ans-ans"></textarea></div>
	 </div>
	 <input type="submit" style="display:none">
</form>
<input type="button" id="sendAll" value="ПРИНЯТЬ">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
$("#sendAll").click(function(){
for (var i = 1; i <= {{ q_forms|length }}; i++){
	$("#" + i).submit();
}
});
</script>

q_forms — это список всех форм, которые приходят на вышеуказанную страницу др. контроллером — прим.

Но не знаю, правильно это или нет, с jquery не работал. Если только средствами django формы отправлять, то нужно для каждой формы создать видимую кнопку type=“submit”, и клиенту придётся каждую форму отправлять отдельно, но это не подходит для клиента. Я хотел бы предоставить отправку всех форм по отдельности в один контроллер нажатием одной кнопки.

FishHook
Alex.py
Я все-таки не понимаю, зачем тут jquery. Допустим, у меня есть такой HTML
 <form>
{# form 1 #}
<input name='form1__field1' /> 
<input name='form1__field2' /> 
{# form 2 #}
<input name='form2__field1' /> 
<input name='form2__field2' /> 
{# form 3 #}
<input name='form3__field1' /> 
<input type=''submit" />
</form>

В кверисете вы получите словарь со всеми этими филдами и можете подставлять его в конструктор форм, формы сами разберуться с префиксами. Зачем тут jquery?
Alex.py
FishHook
В кверисете вы получите словарь со всеми этими филдами и можете поставлять его в конструктор форм, формы сами разберуться с префиксами.

Ну я в разметке посмотрел, всё так и происходит примерно: атрибут name получает значение в формате имя_класса_формы-имя_поля

Только у Вас в примере двойное нижнее подчёркивание.

Значит мне нужно создать 3 formset'а на каждый кл. форм с префиксами соответствующих классов.
FishHook
Alex.py
У вас вопрос еще остался? Я правда не понимаю ваших затруднений
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB