Мені потрібно було зробити щось подібне деякий час тому, і далі описано, що ми закінчуємо.
У нас є дві таблиці, Item і UnfinishedItem. Коли користувач заповнює дані майстра, дані зберігаються в таблиці UnfinishedItem. На кожному кроці майстра сервер перевіряє дані, введені під час цього кроку. Коли користувач закінчує роботу з майстром, майстер надає приховану форму / лише для читання на сторінці підтвердження, де відображаються всі дані для надсилання. Користувач може переглянути цю сторінку та повернутися до відповідного кроку для виправлення помилок. Після того, як користувач задоволений своїми записами, користувач натискає кнопку "Надіслати", а потім майстер подає всі дані в поля прихованої / лише для читання форми на сервер API. Коли сервер API обробляє цей запит, він повторює всі перевірки, які він робив під час кожного кроку майстра, та виконує додаткові перевірки, які не вписуються в окремі етапи (наприклад, глобальні перевірки, дорогі перевірки).
Переваги двох табличних підходів:
у базі даних ви можете мати більш жорсткі обмеження в таблиці Item, ніж у таблиці UnfinishedItem; вам не потрібно мати додаткові стовпці, які фактично знадобляться після завершення роботи майстра.
Сукупні запити в готових елементах для звітування простіші, оскільки вам не потрібно пам'ятати, щоб виключити UnfinishedItems. У нашому випадку нам ніколи не потрібно було робити сукупні запити між Item і UnfinishedItems, тому це не проблема.
Недолік:
- Це схильне до дублювання логіки перевірки. Веб-фреймворк, який ми використовували, Django, робить це трохи більш прийнятним, оскільки ми використовували успадкування моделі з трохи мета магії, щоб змінити обмеження, які нам потрібно відрізняти в Item і UnfinishedItem. Django генерує більшу частину бази даних та валідацію форми з моделі, і нам потрібно лише зламати декілька додаткових перевірок поверх неї.
Інші можливості, які я розглянув, і чому ми з ними не пішли:
- збереження даних у файлах cookie або локальному сховищі: користувач не може продовжувати подання з іншого пристрою або якщо видалити історію браузера
- зберігати UnfinishedItem як неструктуровані дані (наприклад, JSON) у базі даних або вторинній сховищі даних: мені доведеться визначити логіку розбору і не можу використовувати автоматичну перевірку моделі / форми Django.
- зробіть покрокову перевірку на стороні клієнта: мені доведеться дублювати логіку перевірки між Python / Django та JavaScript.