django несколько моделей в одной форме

Как передать несколько моделей приложения в одном просмотре? [Джанго]

Мне трудно передать две модели приложений в одно представление. У меня 2 приложения:

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

Когда я вызываю что-то подобное в шаблонах, это не работает. << author.avatar >> не отображается:

Приложение «Мои сообщения» urls.py :

Любая помощь будет принята с благодарностью! Заранее спасибо!

Вот мой пост models.py

Ответ @Gagik и @Daniel решил мою проблему. Вместо этого мне просто нужно использовать этот тег:

Я не менял код выше. За исключением того, что мне не нужна эта строка:

2 ответа

Вам необходимо связать модели Author и Post друг с другом с помощью файла ForeignKey, например:

Затем, когда вы сможете получить доступ к своему аватару через post.author.

Обновление ответа после обновления вопроса. Думаю, вам нужно обновить свой шаблон следующим образом. используйте post.post_author.avatar для доступа к нужному вам аватару:

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

Потому что, когда у вас есть ForeignKey, у вас уже есть доступ к автору через объект post.

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

Нет необходимости собирать всех авторов и передавать их в шаблон в вашем представлении, как вы это делаете.

Источник

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

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

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

Предпосылка

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вывод

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

Источник

Создание форм из моделей ¶

ModelForm ¶

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

По этой причине Django предоставляет вспомогательный класс, который позволяет вам создавать Form класс из модели Django.

Типы полей ¶

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

Как и следовало ожидать, ForeignKey и ManyToManyField типы полей модели являются частными случаями:

Кроме того, каждое сгенерированное поле формы имеет следующие атрибуты:

Наконец, обратите внимание, что вы можете переопределить поле формы, используемое для данного поля модели. См. Раздел « Замена полей по умолчанию» ниже.

Полный пример ¶

Рассмотрим этот набор моделей:

С этими моделями приведенные ModelForm выше подклассы были бы примерно эквивалентны этому (единственное отличие состоит в save() методе, который мы обсудим чуть позже):

Проверка на ModelForm ¶

Есть два основных этапа проверки ModelForm :

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

Переопределение метода clean () ¶

Вы можете переопределить clean() метод в форме модели, чтобы обеспечить дополнительную проверку так же, как и в обычной форме.

Экземпляр формы модели, прикрепленный к объекту модели, будет содержать instance атрибут, который дает его методам доступ к этому конкретному экземпляру модели.

Взаимодействие с валидацией модели ¶

В рамках процесса проверки ModelForm будет вызывать clean() метод каждого поля в вашей модели, у которого есть соответствующее поле в вашей форме. Если вы исключили какие-либо поля модели, проверка этих полей выполняться не будет. См. Документацию по проверке формы, чтобы узнать больше о том, как работают очистка и проверка полей.

Соображения относительно модели error_messages ¶

Сообщения об ошибках, определенные на уровне или на уровне мета-формы, всегда имеют приоритет над сообщениями об ошибках, определенными на уровне. form field model field

Вы можете переопределить сообщения об ошибках, NON_FIELD_ERRORS возникающие при проверке модели, добавив NON_FIELD_ERRORS ключ в error_messages словарь ModelForm внутреннего Meta класса:

save() Метод ¶

У каждого ModelForm тоже есть save() метод. Этот метод создает и сохраняет объект базы данных из данных, привязанных к форме. Подкласс ModelForm может принимать существующий экземпляр модели в качестве аргумента ключевого слова instance ; если он предоставлен, save() обновит этот экземпляр. Если он не указан, save() будет создан новый экземпляр указанной модели:

modelformset_factory() используется formset_factory() для создания наборов форм. Это означает, что модельный набор форм является расширением базового набора форм, который знает, как взаимодействовать с конкретной моделью.

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

_ptr ) вместо id поля.

Изменение набора запросов ¶

По умолчанию, когда вы создаете набор форм из модели, набор форм будет использовать набор запросов, который включает все объекты в модели (например, Author.objects.all() ). Вы можете изменить это поведение, используя queryset аргумент:

Затем передайте свой BaseAuthorFormSet класс фабричной функции:

Изменение формы ¶

Затем передайте форму модели в функцию factory:

Указание виджетов для использования в форме с помощью widgets ¶

Используя widgets параметр, вы можете указать словарь значений для настройки ModelForm класса виджета для определенного поля. Это работает так же, как widgets словарь во внутреннем Meta классе ModelForm произведения:

Включение локализации для полей с localized_fields ¶

С помощью localized_fields параметра вы можете включить локализацию полей в форме.

Предоставление начальных значений ¶

Сохранение объектов в наборе форм ¶

Передайте, commit=False чтобы вернуть несохраненные экземпляры модели:

После вызова save() ваш модельный набор форм будет иметь три новых атрибута, содержащих изменения набора форм:

models.BaseModelFormSet. changed_objects ¶ models.BaseModelFormSet. deleted_objects ¶ models.BaseModelFormSet. new_objects ¶

Ограничение количества редактируемых объектов ¶

max_num не препятствует отображению существующих объектов:

Кроме того, extra=0 это не препятствует созданию новых экземпляров модели, поскольку вы можете добавлять дополнительные формы с помощью JavaScript или отправлять дополнительные данные POST. Наборы форм еще не предоставляют функциональные возможности для представления «только редактирование», которое предотвращает создание новых экземпляров.

Если значение max_num больше, чем количество существующих связанных объектов, extra в набор форм будет добавлено до дополнительных пустых форм, при условии, что общее количество форм не превышает max_num :

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

Наборы форм очень похожи на наборы форм. Допустим, мы хотим представить набор форм для редактирования Author экземпляров модели:

Перекрытие clean() на ModelFormSet ¶

Использование настраиваемого набора запросов ¶

Как указывалось ранее, вы можете переопределить набор запросов по умолчанию, используемый набором форм модели:

Обратите внимание, что в этом примере мы передаем queryset аргумент как в случаях, так POST и в GET случаях.

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

Есть три способа визуализировать набор форм в шаблоне Django.

Во-первых, вы можете позволить набору форм выполнять большую часть работы:

Во-вторых, вы можете визуализировать набор форм вручную, но пусть форма сама сама себя обрабатывает:

В-третьих, вы можете вручную отобразить каждое поле:

Если вы решите использовать этот третий метод и не перебираете поля с помощью цикла, вам необходимо отобразить поле первичного ключа. Например, если вы отдавая и поле модели: <% for %>name age

Встроенные наборы форм ¶

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

Переопределение методов на InlineFormSet ¶

Например, если вы хотите переопределить clean() :

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

Более одного внешнего ключа для одной модели ¶

Чтобы решить эту проблему, вы можете использовать fk_name для inlineformset_factory() :

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

Вы можете захотеть предоставить представление, которое позволяет пользователю редактировать связанные объекты модели. Вот как это сделать:

Указание виджетов для использования во встроенной форме ¶

Источник

Многостраничные формы в 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 Formsets управляет сложными повторяющимися полями форм в представлении. Используя формуляры, вы можете узнать, сколько форм было изначально, какие были изменены, а какие должны быть удалены.
Подобно формам и моделям форм, Django предлагает наборы моделей форм, которые упрощают задачу создания набора форм для формы, обрабатывающей несколько экземпляров модели.

Django также предоставляет встроенные наборы форм, которые можно использовать для обработки набора объектов, принадлежащих общему внешнему ключу.
В приведенных ниже примерах моделей мы можем написать inline-formset для обработки всех дочерних элементов, для родителя или всех адресов дочерних элементов.

Шаг 1: Создание базового inline-formset

Шаг 2. Прикрепление вложенного набор форм для каждой формы, как показано ниже. Супер-класс BaseInlineFormSet определяет метод add_fields, который отвечает за добавление полей для каждой формы в наборе форм. Также, здесь мы можем написать логику, чтобы связать вложенный набор форм.

Примечание: Здесь мы создали новое свойство с именем «form.nested», которое содержит вложенный набор форм (AddressFormset).

Шаг 3. Обработка набора форм и вложенных наборов форм в представлениях

Шаг 4: Визуализация вложенного набора форм в шаблоне

Есть несколько моментов, на которые нужно обратить внимание:

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

2. Сохранение данных. При сохранении формы также необходимо сохранять дополнения и изменения к формам во вложенном наборе форм.

Когда страница отправлена, мы вызываем formset.is_valid () для проверки форм. Мы переопределяем is_valid в нашем наборе форм, чтобы добавить проверку и для вложенных наборов форм.

На этом проверка форм и вложенных форм завершается. Теперь нам нужно обработать сохраненное. Для этого необходимо переопределить метод save для сохранения родительского набора форм и всех вложенных наборов форм.

Источник

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