Лучшая практика: Обработка сложной динамической формы на одной странице с помощью Django

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

Упрощенный пример:

                                                               --- Shift 1 --> Form #1 
                                    --- Yes -- What shift? -- |
                                    |                          --- Shift 2 --> Form #2
                                    | 
Enter Date ---   Did you work?   ---|
                                    |
                                    |                            --- Yes --> Form #3
                                     --- No -- Was this PTO? ---|
                                                                 --- No --> Form #4

Я пытаюсь найти наиболее эффективный/питонический способ справиться с вышеописанным.

Возможные подходы:

  1. Много jquery, ajax и представлений на основе функций. Это моя текущая установка, но я хотел бы перевести ее на CBV и ModelForms, если это возможно, потому что мой текущий код составляет около 2000 строк (с 10+ ajax-функциями, 10+ ссылками, обрабатывающими представления, и слишком большим количеством полей ввода, чтобы считать) в моем шаблоне/модели/представлениях только для загрузки/обработки этой формы. Это полный кошмар для поддержки.
  2. Одностраничник с ModelForms, встроенными в динамический div. Страница с формой вызывает jquery load в зависимости от ваших ответов на вопросы. Например, если вы ответили "Сегодня", "Да", "Смена 1", я бы вызвал $("#form-embed").load("/forms/form1/"), который содержит форму №1 ModelForm. С этим есть несколько проблем: 1. Некоторые из "вопросов" на самом деле являются полями формы, и если я перезагружаю пустую форму, то это поле будет пустым. Я мог бы решить это с помощью JS на фронт-энде или пользовательской очистки на бэк-энде, но в итоге получается много кода. И 2. POSTing формы и обработка ошибок были бы довольно сложными с таким количеством потенциальных форм на одной странице.
  3. То же, что и выше, но с использованием Iframe. Это решает некоторые из вышеупомянутых проблем, но почему-то кажется "неприятным" и заставляет меня беспокоиться об отзывчивом пользовательском интерфейсе/совместимости на разных платформах.
  4. .
  5. Multiple pages, each with its own form. This eliminates the convenience of a single-page approach, which I'd really like to keep if possible.
  6. Combine all my models into a single model. This gets pretty complex pretty quickly because the actual fields involved on each form are very different, and the logic handling would therefore get messy and bloated.
  7. Create a new single model with a corresponding modelform for use only with this form that contains all possible fields, dynamically displayed via JS based on user input, then routes the fields to the appropriate models after submission.
  8. Don't use modelforms, instead create my own custom Form Class that involves all possible fields, then route to the appropriate models after submission. Use JS to display/hide fields based on user input.

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

Моя надежда на фронтенд - максимизировать ModelForm и управление шаблонами Django, минимизируя JS. Я надеюсь, что бэкенд будет максимально использовать CBV/ModelForm для настройки, минимизируя FBV. Моя общая цель - уменьшить объем кода и улучшить сопровождаемость/модификацию.

Похоже, что функциональность, которую я искал - это представление на основе классов FormView и forms.Form (не forms.ModelFormView).

В forms.py я создал форму forms.Form, которая содержала все возможные поля (в итоге их оказалось около 10, причем некоторые можно было использовать повторно. Пришлось сделать многие из них required=False), затем загрузил их все одновременно в отдельные div'ы внутри FormView. Каждый div разделял название поля, поэтому я мог легко скрывать/показывать каждый div с помощью простого JS в зависимости от того, какую комбинацию полей я хотел отобразить на основе пользовательского ввода.

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

Затем я использовал миксин def clean(self) в моем forms.py для обработки каждой отдельной формы.

Я еще не все закончил, но уже кажется, что длина моего кода сократится с 2000+ до пары сотен или около того. Плюс это будет намного легче поддерживать, и большая часть моей логики останется на стороне сервера, а не в html-файле.

Вернуться на верх