django несколько форм на одной странице

Django – две формы в одном view

Иногда возникает необходимость показать две формы на одной странице.
Мы приводим перевод очень полезной статьи на эту тему.

Как это работает? Идея очень проста. Нужно сделать одно view, которое рендерит обе формы. Более того, в этом view используется только метод GET, поэтому возможности сделать POST не будет. Но в этом главном view будет еще два view, которые отвечают за обработку POST запросов для обеих форм. Вот простая картинка, наглядно демонстрирующая суть идеи: Django %D0%94%D0%B2%D0%B5 %D1%84%D0%BE%D1%80%D0%BC%D1%8B %D0%BD%D0%B0 %D0%BE%D0%B4%D0%BD%D0%BE%D0%B9 %D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B5

Переходим к коду. Вот первое view, ответственное за рендеринг форм:

Это просто TemplateView, ответвтсенная за запрос GET. Сначала я получаю форму question и форму answer. Затем я добавляю эти формы в контекст context dictionary делаю рендеринг в sample_forms/index.html.

В этом примере sample_forms/index.html выглядит так:

Здесь обрабатываются два разных действия, поэтому POST обращается к двум разным URL: форма question к question_form/submit и форма answer к answer_form/submit.

View, обрабатывающие запросы POST для обеих форм выглядит так:

Эти формы почти одинаковые, поэтому опишу одну из них: QuestionFormView.
В POST, я подтверждаю question_form запросом POST из пользовательского ввода. Сразу же после этого инициализируется пустая answer_form – так как если в первой форме будут ошибки я хочу отразить из во второй форме. Без этого будут обрабатываться только форма без ошибок. Следующие строки просты: проверяем, есть ли в форме ошибки: если нет, сохраняет форму и рендерим index.html в дополнительной переменной success. Зачем? Чтобы получить возможность на этой странице обработать информацию для пользователя:

Если пользовательский ввод некорректен, обрабатываются обе формы: одна с ошибками, вторая – без.

Источник

Обработка нескольких форм на одной странице в Django

Узнайте, как реализовать две разные формы на одной странице способом “Django”.

Недавно мне пришлось реализовать обработку двух разных форм на одной странице в Django. Благодаря тому, что этот вариант использования удивительно распространен, я не смог найти много примеров того, как это сделать “Джанго”.

Предпосылка

Допустим, на странице есть две формы. Одна форма для подписки пользователя, которая принимает только электронную почту, а другая-контактная форма, которая принимает заголовок и описание. Мы должны обрабатывать обе формы в одном и том же представлении.

Первый разрез

Давайте обработаем их с помощью представлений, основанных на функциях Django.

Основная проблема с этим подходом заключается в том, что нет надежного способа инициировать только проверку и отправку формы, которая была отправлена. Кроме того, это неуклюжий рефакторинг логики после отправки в этот код.

Как насчет использования представлений на основе классов? Чтобы понять, как мы можем использовать представление на основе классов для решения этой проблемы, давайте посмотрим, как одна форма обрабатывается с помощью CBVs.

Django FormView является основным классом для обработки форм таким образом. Как минимум, ему нужно:

Вот как выглядит иерархия обработки форм на основе классов Django:

Проектирование нашего многоформного погрузочно-разгрузочного механизма

Давайте попробуем имитировать то же самое для нескольких форм. Наши критерии проектирования таковы:

Вместо одного класса у нас будет dict классов форм. Мы следуем тому же правилу и для успешных URL-адресов. Вполне вероятно, что каждая форма на странице имеет свой собственный URL-адрес, который будет перенаправлен после успешной отправки.

Типичным шаблоном использования будет:

Мы также разрабатываем аналогичную иерархию классов для обработки нескольких форм.

Второе изменение состоит в том, чтобы убедиться, что этот атрибут action предварительно заполнен правильным именем формы из form_classes dict. Мы слегка изменяем get_initial функцию, чтобы сделать это, предоставляя разработчикам возможность переопределить это на основе каждой формы.

Серьезно, у меня было требование разработать несколько форм, каждая из которых имела свой собственный набор начальных аргументов.

Существует много возможностей для улучшения, например, прибегать к некоторому поведению по умолчанию, когда функция form

формы не существует, или создавать исключения, но этого должно быть достаточно для большинства случаев.

Мы можем ссылаться на эти формы в шаблоне по имени ключа dict. Например, вышеприведенные формы будут отображаться в шаблоне следующим образом:

Вывод

Похоже, мы выполнили наши критерии проектирования, сделав обработку форм более модульной, которая может быть повторно использована в разных проектах. Мы также можем расширить это, чтобы добавить больше форм в нашем представлении и рефакторинг нашей логики только для одной формы, если это необходимо. Кроме того, код очень похож на CBVS существующей формы без большой кривой обучения.

Источник

Правильный способ обработки нескольких форм на одной странице в Django

у меня есть страница шаблона, ожидающая две формы. Если я просто использую одну форму, все в порядке, как в этом типичном примере:

Если я хочу работать с несколькими формами, как я могу сообщить представлению, что я отправляю только одну из форм, а не другую (т. е. это все еще запрос.Сообщение, но я хочу только обработать форму, для которой произошла отправка)?

это решение на основе ответа, где expectedphrase и bannedphrase являются имена кнопок отправки для различных форм и expectedphraseform и bannedphraseform формы.

9 ответов

У вас есть несколько вариантов:

поместите разные URL-адреса в действие для двух форм. Тогда у вас будут две разные функции просмотра для работы с двумя разными формами.

прочитайте значения кнопки отправки из данных POST. Вы можете сказать, какая кнопка отправки была нажата:как я могу построить несколько кнопок отправки формы django?

метод для будущей ссылки-это что-то вроде этого. bannedphraseform-первая форма, а expectedphraseform-вторая. Если первый попадает, второй пропускается (что является разумным предположением в этом случае):

представления на основе классов Django предоставляют общий вид FormView, но для всех целей и задач он предназначен только для обработки одной формы.

один из способов обработки нескольких форм с одним и тем же целевым url-адресом действия с использованием общих представлений Django-расширить «TemplateView», как показано ниже; я использую этот подход достаточно часто, чтобы я превратил его в шаблон Eclipse IDE.

шаблон html имеет следующий эффект:

Мне нужно несколько форм, которые независимо проверяются на одной странице. Ключевые понятия, которые мне не хватало, были 1) Использование префикса формы для имени кнопки отправки и 2) неограниченная форма не вызывает проверку. Если это поможет кому-то еще, вот мой упрощенный пример двух форм AForm и BForm с использованием TemplateView на основе ответов @adam-nelson и @daniel-sokolowski и комментария @zeraien (https://stackoverflow.com/a/17303480/2680349):

Я надеюсь, что это поможет в будущем.

Если вы используете подход с представлениями на основе классов и различными «действиями» attrs, я имею в виду

поместите разные URL-адреса в действие для двух форм. Тогда у вас будут две разные функции просмотра для работы с двумя разными формами.

вы можете легко обрабатывать ошибки из разных форм, используя перегруженные get_context_data способ, электронные.х:

Источник

Наборы форм ¶

Вы можете разрешить пользователю создавать сразу несколько статей. Чтобы создать набор форм из ArticleForm :

Как видите, отображается только одна пустая форма. Количество отображаемых пустых форм контролируется extra параметром. По умолчанию formset_factory() определяет одну дополнительную форму; в следующем примере будет создан класс набора форм для отображения двух пустых форм:

Итерация по набору форм будет отображать формы в том порядке, в котором они были созданы. Вы можете изменить этот порядок, предоставив альтернативную реализацию __iter__() метода.

Использование исходных данных с набором форм ¶

Выше показаны три формы. Один для исходных данных, которые были переданы, и две дополнительные формы. Также обратите внимание, что мы передаем список словарей в качестве исходных данных.

Ограничение максимального количества форм ¶

max_num Параметр formset_factory() дает возможность ограничить количество форм formset будет отображаться:

Ограничение максимального количества экземпляров форм ¶

Проверка набора форм ¶

Мы не передали никаких данных в набор форм, что привело к правильной форме. Набор форм достаточно умен, чтобы игнорировать лишние формы, которые не были изменены. Если мы предоставим недействительную статью:

Как мы видим, formset.errors это список, записи которого соответствуют формам в наборе форм. Проверка была выполнена для каждой из двух форм, и для второго элемента отображается ожидаемое сообщение об ошибке.

Чтобы проверить, сколько ошибок в наборе форм, мы можем использовать total_error_count метод:

Мы также можем проверить, отличаются ли данные формы от исходных данных (т.е. форма была отправлена ​​без данных):

Понимание ManagementForm ¶

Он используется для отслеживания количества отображаемых экземпляров форм. Если вы добавляете новые формы через JavaScript, вам также следует увеличивать количество полей в этой форме. С другой стороны, если вы используете JavaScript, чтобы разрешить удаление существующих объектов, вам необходимо убедиться, что удаляемые правильно помечены для удаления, включив их form-#-DELETE в POST данные. Ожидается, что все формы присутствуют в POST данных независимо.

Форма управления доступна как атрибут самого набора форм. При визуализации набора форм в шаблоне вы можете включить все данные управления путем визуализации (при необходимости подставляя имя набора форм). << my_formset.management_form >>

formset.is_valid() теперь возвращается, False а не вызывает исключение, когда форма управления отсутствует или была изменена.

total_form_count и initial_form_count ¶

total_form_count возвращает общее количество форм в этом наборе форм. initial_form_count возвращает количество форм в наборе форм, которые были предварительно заполнены, а также используется для определения необходимого количества форм. Вам, вероятно, никогда не понадобится отменять любой из этих методов, поэтому, пожалуйста, убедитесь, что вы понимаете, что они делают, прежде чем делать это.

empty_form ¶

BaseFormSet предоставляет дополнительный атрибут, empty_form который возвращает экземпляр формы с префиксом __prefix__ для упрощения использования в динамических формах с помощью JavaScript.

error_messages ¶

А вот собственное сообщение об ошибке:

Проверка пользовательского набора форм ¶

В наборе форм есть clean метод, аналогичный методу Form класса. Здесь вы определяете свою собственную проверку, которая работает на уровне набора форм:

Проверка количества форм в наборе форм ¶

Django предоставляет несколько способов проверить минимальное или максимальное количество отправленных форм. Приложения, которым требуется более настраиваемая проверка количества форм, должны использовать настраиваемую проверку набора форм.

validate_max ¶

validate_max=True max_num строго проверяет соответствие, даже если max_num было превышено из-за чрезмерного количества предоставленных исходных данных.

validate_min ¶

Работа с заказом и удалением форм ¶

formset_factory() Обеспечивает два дополнительных параметров can_order и can_delete помочь с упорядочением форм в FormSets и удаление форм из formset.

can_order ¶

По умолчанию: False

Позволяет создать набор форм с возможностью заказа:

ordering_widget ¶

Установите, ordering_widget чтобы указать класс виджета, который будет использоваться с can_order :

get_ordering_widget ¶

Переопределите, get_ordering_widget() если вам нужно предоставить экземпляр виджета для использования с can_order :

can_delete ¶

По умолчанию: False

Позволяет создать набор форм с возможностью выбора форм для удаления:

can_delete_extra ¶

При настройке can_delete=True указание can_delete_extra=False удалит возможность удаления лишних форм.

Добавление дополнительных полей в набор форм ¶

Если вам нужно добавить дополнительные поля в набор форм, это легко сделать. Базовый класс набора форм предоставляет add_fields метод. Вы можете переопределить этот метод, чтобы добавить свои собственные поля или даже переопределить поля / атрибуты по умолчанию для полей порядка и удаления:

Передача пользовательских параметров в формы набора форм ¶

Настройка префикса набора форм ¶

Например, в случае по умолчанию вы можете увидеть:

Но с ArticleFormset(prefix=’article’) этим становится:

Использование набора форм в представлениях и шаблонах ¶

manage_articles.html Шаблон может выглядеть следующим образом :

Однако есть небольшое сокращение для вышеупомянутого, позволяя самому набору форм работать с формой управления:

Вышеупомянутое заканчивается вызовом as_table метода в классе набора форм.

Рендеринг вручную can_delete и can_order ¶

Если вы вручную визуализируете поля в шаблоне, вы можете визуализировать can_delete параметр с помощью : << form.DELETE >>

Использование нескольких наборов форм в представлении ¶

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

Затем вы должны отрендерить наборы форм как обычно. Важно отметить, что вам необходимо передавать prefix как POST, так и не-POST случаи, чтобы они отображались и обрабатывались правильно.

Источник

Многостраничные формы в Django

Введение

Большинство онлайн-форм помещаются на одной странице. Подумайте о форме «присоединиться к нашему форуму» или «свяжитесь с нами», в которую пользователь вводит имя, адрес электронной почты и, возможно, несколько других элементов информации. Если вы встраиваете такую функциональность в сайт Django, вы можете воспользоваться встроенными в Django классами форм. Это особенно удобно при работе с формами модели, где поля формы соответствуют полям модели, которые будут записаны в вашей базе данных.

Итак, давайте сделаем это. В посте ниже мы рассмотрим пошаговую процедуру создания многостраничной формы заявки на работу. Мы начнем с самой простой функциональности, а затем сделаем ее (немного) более сложной. Наиболее важные модули («models.py», «forms.py» и «views.py») будут воспроизведены здесь, но рабочий, автономный проект доступен на GitHub.

Не стесняйтесь клонировать репозиторий, запустить демо-версию и использовать или модифицировать ее для своих собственных целей.

Отказ от ответственности: нижеприведенный подход я лично использовал для создания многостраничных форм на нескольких разных веб-сайтах. Я уверен, что есть и другие подходы, но это мой личный взгляд на проблему.

Требования

Модель

models.py

(Обратите внимание, что этот модуль относится к модулю под названием «constants», который определяет значения для «stage» и используется как здесь, так и в «views.py». Этот модуль не воспроизводится в этом сообщении в блоге, но если вы загрузите полный проект от Github, вы найдете его там.)

Методы create_session_hash() и __init __() в модели поддерживают это. Обратите внимание на использование цикла while для защиты от исчезающей крошечной вероятности того, что мы случайным образом сгенерируем хеш, который уже существует в модели. Поскольку существует 2^160 различных 40-символьных шестнадцатеричных хеш-кодов, мы не будем долго зацикливаться на этом цикле (и почти наверняка не на всех).

Наконец, нам нужно что-то, чтобы разделить поля модели на группы, которые будут отображаться на странице 1, странице 2 и странице 3 формы. Метод get_fields_by_stage() делает это для нас. Этот метод не требует экземпляра JobApplication для работы, поэтому я сделал его статическим методом.

Форма

Поля типичной формы Django жестко закодированы. Может выглядеть так:

forms.py

Представление

Вот последний большой кусок этого проекта: «views.py»:

views.py

(Обратите внимание, что этот модуль ссылается на шаблон «job_application.html» и второе представление, называемое «thank_you». Его использование метода reverse() также подразумевает существование «urls.py». Эти элементы не воспроизводятся в этом в блоге, но если вы загрузите полный проект с Github, вы найдете их там.)

Подробная информация о различных методах этого представления в комментариях выше, но вкратце:

Обязательные поля и проверка

На данный момент наша многостраничная форма работает, но в ней все еще есть некоторые странные вещи. С одной стороны, мы вообще не проверяем ввод пользователя. У нас также нет возможности сделать поле обязательным. Как ни странно, поле stage может быть изменено пользователем при отправке формы!

Итак, давайте рассмотрим эти проблемы сейчас:

Проверка ввода

forms.py

Обязательные поля и скрытые поля

Для начала давайте добавим пару новых строк в нашу модель. Возможно, поместите их прямо над определением метода __init __() :

models.py

Обратите внимание, что эти новые переменные определены на уровне класса. Они будут одинаковыми для каждого экземпляра нашей модели, но это нормально, потому что мы будем только читать с них.

forms.py

Заключение

Это подводит нас к концу нашего обсуждения того, как создать многостраничную форму в Django. Мы создали модель JobApplication и сопроводительную форму с тремя страницами, заполненными проверкой ввода, обязательными и скрытыми полями.

Опять же, для рабочего примера, вы можете клонировать кодовую базу из GitHub. Рабочий пример содержит все отсутствующие модули и шаблоны, упомянутые выше, а также позволяет просматривать отправленные объекты JobApplication с помощью встроенной админки Django.

models.py

(Рабочий пример в GitHub также реализует эту функцию).

Мы также могли бы добавить кнопку «назад» в форме, чтобы позволить пользователю вернуться к уже отправленным страницам, и кнопку «вперед», чтобы они могли быстро вернуться туда, где они были до того, как использовали кнопку «назад». Возможно, некоторые поля должны быть обязательными, только если другим полям даны значения. И, возможно, продвижение пользователя от страницы 1 формы до конца не должно быть одинаковым для всех пользователей. Мы могли бы реализовать страницы формы, которые отображаются только в том случае, если пользователь ввел определенные значения ранее.

Возможно, эти темы могут стать предметом последующего сообщения. До тех пор, счастливого программирования!

Источник

Понравилась статья? Поделить с друзьями:
Добавить комментарий
  • Как сделать успешный бизнес на ритуальных услугах
  • Выездной кейтеринг в России
  • Риски бизнеса: без чего не обойтись на пути к успеху
  • django несколько моделей в одной форме
  • django название приложения в админке на русском