Nomad
NomadOct. 20, 2020, 9:20 a.m.

Django form vs modelForm

django, Form, modelform

всем привет.

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

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

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

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

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

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

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

4
Илья Чичак
  • Oct. 20, 2020, 10:04 a.m.
  • (edited)
  • The answer was marked as a solution.

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

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

    Nomad
    • Oct. 20, 2020, 3:17 p.m.
    • (edited)

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

      Илья Чичак
      • Oct. 21, 2020, 5 a.m.
      • (edited)

      напрямую данные из 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
        • Oct. 21, 2020, 5:28 a.m.

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

          Comments

          Only authorized users can post comments.
          Please, Log in or Sign up
          AD

          C ++ - Test 004. Pointers, Arrays and Loops

          • Result:50points,
          • Rating points-4
          m

          C ++ - Test 004. Pointers, Arrays and Loops

          • Result:80points,
          • Rating points4
          m

          C ++ - Test 004. Pointers, Arrays and Loops

          • Result:20points,
          • Rating points-10
          Last comments
          Evgenii Legotckoi
          Evgenii LegotckoiNov. 1, 2024, 12:37 a.m.
          Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
          A
          ALO1ZEOct. 19, 2024, 6:19 p.m.
          Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
          ИМ
          Игорь МаксимовOct. 5, 2024, 5:51 p.m.
          Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
          d
          dblas5July 5, 2024, 9:02 p.m.
          QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
          k
          kmssrFeb. 9, 2024, 5:43 a.m.
          Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
          Now discuss on the forum
          Evgenii Legotckoi
          Evgenii LegotckoiJune 25, 2024, 1:11 a.m.
          добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
          t
          tonypeachey1Nov. 15, 2024, 5:04 p.m.
          google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
          NSProject
          NSProjectJune 4, 2022, 1:49 p.m.
          Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
          9
          9AnonimOct. 25, 2024, 7:10 p.m.
          Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

          Follow us in social networks