Nomad
Nomad20 октября 2020 г. 9:20

Django form vs modelForm

django, Form, modelform

всем привет.

всем известно что в Django есть очень важное составляющая это формы

по сути при создании формы мы определяем "тип формы" то есть форма связанная с моделью или нет = forms.Form или forms.ModelForm

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

может кто сказать правильно ли так делать или же если даные для какой то модели форма должна быть всегда типа ModelForm ?

или же все зависит от ситуации!?

или правило одно: нету никаких правил )

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

4
Илья Чичак
  • 20 октября 2020 г. 10:04
  • (ред.)
  • Ответ был помечен как решение.

использовать данные напрямую из request.POST - опасно и черевато.
сохранять данные из form.cleaned_data - нормально, но избытачно.
если форма используется для управления объектом модели - УДОБНЕЕ использовать ModelForm, но это не обязательно

проще всего придерживаться догики такой: меняется модель - ModelForm, что-то происходит с несколькими моделями или вообще не меняются модели - Form.

    Nomad
    • 20 октября 2020 г. 15:17
    • (ред.)

    спасибо за исчерпывающий ответ.
    вы писали "использовать данные напрямую из request.POST - опасно и черевато" а чему чревато?
    ведь если мы берем данные из post, и обрабатываем, проверяем их и только после этого сохраняем

      Илья Чичак
      • 21 октября 2020 г. 5:00
      • (ред.)

      напрямую данные из POST - я имел в виду, без проверок и всего прочего

      черевато тем, что там могут быть какие-то плохие данные типа sql-инъекций

      а если их проверять и обрабатывать - зачем делать двойную работу (форма делает начальную валидацию по параметрам своих полей + возможность указать какие-то кастомные проверки в Form.clean())?
      + всетаки какое-никакое разделение ответственности:
      - представление вызывает форму и отдает ответы
      - форма делает все с данными

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

      def my_view(request):  # это долгий, трудоемкий и опасный пусть
          form = MyForm()
          if request.method == 'POST':
              if request.POST.get('param1'):
                  <check it>
              if request.POST.get('param2'):
      
      
      def my_view(request):  # это трудоемкий пусть
          form = MyForm(request.POST or None)
          if form.is_valid():
              mymodel_instance.param = request.POST.get('param')
      
      
      def my_view(request):  # это более менее простой путь
          form = MyForm(request.POST or None)
          if form.is_valid():
              mymodel_instance.param = form.cleaned_data['param']
              ...
      
      
      def my_view(request):  # это, как мне кажется самый понятный и простой путь
          form = MyForm(request.POST or None)
          if form.is_valid():
              form.process() # или save() для ModelForm
              return ...
          return ...
      

      основная мысль - не надо мешать разную логику в одном месте
      пусть view - занимается отбработкой HTTP запросов, а формы - обработкой введеных данных

      опять же, если у тебя логика, которая подразумевается для выполнения над данными формы, используется где-то еще (например в API) - вынеси это в отдельную функцию, это уже получится "слой бизнес логики" (можно погуглить "services layer django"). Как по мне: ниже самый оптимальный вариант:

      # services.py
      
      def create_user(username, password):
          new_user = get_user_model().create_user(username=username, password=password)
          return new_user
      
      # forms.py
      
      class CreateUserForm(forms.Form):
          username = forms.CharField(...)
          password = forms.CharField(...)
          password_confirm = forms.CharField(...)
      
          def clean(self):
              cleaned_data = super().clean()
              if cleaned_data['password'] != cleaned_data['password_confirm']:
                  self.add_error('password_confirm', 'Should be same!')
              if get_user_model().objects.filter(username=cleaned_data['username']).first():
                  self.add_error('username', 'Already exists!')
              return cleaned_data
      
          def process(self):
              return create_user(self.cleaned_data['username'], self.cleaned_data['password'])
      
      # views.py
      
      def create_user(request):
          form = CreateUserForm(request.POST or None)
          if form.is_valid():
              new_user = form.process()
              login(request, new_user)
              return redirect(...)
          return render(request, 'template.html', {'form': form})
      

      это тебе позволит:
      1) быстро и просто локализовать ошибки
      2) покрыть тестами каждый функционал будет сильно проще
      3) просто будет расширять функционал

        Nomad
        • 21 октября 2020 г. 5:28

        спасибо за WOW раскрытие теммы

          Комментарии

          Только авторизованные пользователи могут публиковать комментарии.
          Пожалуйста, авторизуйтесь или зарегистрируйтесь
          г
          • ги
          • 23 апреля 2024 г. 12:51

          C++ - Тест 005. Структуры и Классы

          • Результат:41баллов,
          • Очки рейтинга-8
          l
          • laei
          • 23 апреля 2024 г. 6:19

          C++ - Тест 004. Указатели, Массивы и Циклы

          • Результат:10баллов,
          • Очки рейтинга-10
          l
          • laei
          • 23 апреля 2024 г. 6:17

          C++ - Тест 003. Условия и циклы

          • Результат:50баллов,
          • Очки рейтинга-4
          Последние комментарии
          k
          kmssr8 февраля 2024 г. 15:43
          Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
          АК
          Анатолий Кононенко4 февраля 2024 г. 22:50
          Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
          EVA
          EVA25 декабря 2023 г. 7:30
          Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
          J
          JonnyJo25 декабря 2023 г. 5:38
          Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
          G
          Gvozdik18 декабря 2023 г. 18:01
          Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
          Сейчас обсуждают на форуме
          G
          Gar22 апреля 2024 г. 2:46
          Clipboard Как скопировать окно целиком в clipb?
          DA
          Dr Gangil Academics20 апреля 2024 г. 4:45
          Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
          a
          a_vlasov14 апреля 2024 г. 3:41
          Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
          Павел Дорофеев
          Павел Дорофеев13 апреля 2024 г. 23:35
          QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
          f
          fastrex4 апреля 2024 г. 1:47
          Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

          Следите за нами в социальных сетях