NomadOct. 20, 2020, 7:20 p.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.
4
  • Oct. 20, 2020, 8:04 p.m.
  • (edited)
  • The answer was marked as a solution.

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

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

  • Oct. 21, 2020, 1:17 a.m.
  • (edited)

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

напрямую данные из 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) просто будет расширять функционал

  • Oct. 21, 2020, 3:28 p.m.

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

Comments

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

Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting
E

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

  • Result:80points,
  • Rating points4
SF

C++ - Test 001. The first program and data types

  • Result:73points,
  • Rating points1
E

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

  • Result:57points,
  • Rating points-2
Last comments
D

Django - Tutorial 001. Deploying a site on Django + PostgreSQL + Gunicorn + Nginx

А почему нельзя? Где можно об этом почитать? Киньте, пожалуйста, в меня ссылкой.
D

Django - Tutoral 049. Optimizing Django Performance with a Real Project

Огромное спасибо вам за статью! Для меня стали открытием select_related и prefetch_related
t
  • t1m4
  • Feb. 24, 2021, 1:56 p.m.

Django - Tutorial 052. Redefining a User Model

В данном случае я заходил под superuser но все равно не появлялись эти поля

Django - Tutorial 001. Deploying a site on Django + PostgreSQL + Gunicorn + Nginx

Поднял сервис с помощью systemd, вот по этому мануалу: https://habr.com/ru/post/501414/
t
  • t1m4
  • Feb. 23, 2021, 6:11 p.m.

Django - Tutorial 052. Redefining a User Model

А как дать ему эти права?
Now discuss on the forum
M

как добавить списки в список, которые созданы динамически

Привет всем! Смотрите новое: https://cazino.website/luchshie-kazino/ лучшие онлайн казино россии - За регистрацию предоставляют до 225 фриспинов бесплатно + 100% бонуса до 500$ на первый д…

Не отдаётся статика на виртуальной машине

В итоге выставил 775 на все файлы проекта и всё заработало. Но я не уверен, что так правильно.
P
  • Pisych
  • March 3, 2021, 12:06 p.m.

Вывод данных из связанных таблиц.

Не знаю, правильно ли... Но работает <body>{% for i in CatList %} <ul> <li><h3>{{i.title}}</h3></li>{% for j in ProdList %}<ul>{…
M

нужна помощь с проектом qt c++

дали задание, на несколько дней. собираюсь делать, но хотел бы получить помощь более опытных людей, чтобы подкорректировать себя и подстраховаться. каким образом это можно сделать? …

QScrollArea dynamically add QCheckBoxes

Всё правильно. Это просто спамер, который отправился в вечный бан.
About
Services
© EVILEG 2015-2020
Recommend hosting TIMEWEB