如何实现从视图到表单的所有业务逻辑? - python

我正在开发一个Web应用程序,我想将视图中的逻辑移至表单。在视图中,我只想保留验证检查。那是:

例:

def myformview(request):
    if request.POST:
        form = MForm(request.POST)
        if form.is_valid():
            form.save()
            redirect("to-some-view")

    render(request, "template_name.html", {
        'form': form
    })

这是我的views.py:

def login_user(request):
    if request.method == 'POST':
        login_form = Login(request.POST)
        if login_form.is_valid():
            email = login_form.cleaned_data['email']
            password = login_form.cleaned_data.get('password')
            user = authenticate(email=email, password=password)
            if user in User.objects.all():
                login(request, user)
                return HttpResponseRedirect(reverse('dashboard'))
            else:
                return render(request, 'todoapp/waiting_2.html')

    return render(request, 'registration/login.html', {'form': Login()})

这是我的forms.py:

class Login(forms.Form):
    email = forms.EmailField(max_length=250)
    password = forms.CharField(widget=forms.PasswordInput)

目前一切正常。我只想将视图中的逻辑移到表单。而已。

编辑:
我更改了forms.py和views.py,但仍无法正常工作,并且出现了Page Not Found 404错误。

这是我的新forms.py:

class Login(forms.Form):
    email = forms.EmailField(max_length=250)
    password = forms.CharField(widget=forms.PasswordInput)

    def login_user(self):
        email = self.cleaned_data['email']
        password = self.cleaned_data.get('password')
        user = authenticate(email=email, password=password)
        if user in User.objects.all():
            login(self, user)
        else:
            return render(self, 'todoapp/waiting_2.html')

这是我的新views.py ::

def login_user(request):
    if request.method == 'POST':
        login_form = Login(request.POST)
        if login_form.is_valid():
            return HttpResponseRedirect(reverse('dashboard'))
        else:
            return render(request, 'todoapp/waiting_2.html')
    return render(request, 'registration/login.html', {'form': Login()})

这是我的urls.py:

from django.conf.urls import url
from .import views

urlpatterns = [
    url(r'^index/', views.index, name='index'),
    url(r'^register/', views.register, name='register'),
    url(r'^login/', views.login_user, name='login_user'),
    url(r'^dashboard/', views.dashboard, name='dashboard'),
    url(r'^logout_user/', views.logout_user, name='logout_user'),
    url(r'^auth_users/', views.auth_users, name='auth_users'),
    # url(r'^authorize_final', views.authorize_final, name='authorize_final'),
    url(r'^assigntask', views.assigntask, name='assigntask'),
    # url(r'^assign', views.assign, name='assign'),
    url(r'^task_list', views.view_task_list, name='view_task_list'),
    # url(r'^delete_task', views.delete_task, name='delete_task'),
]

我得到的错误是:

AttributeError at /login/

'Login' object has no attribute 'session'

追溯:

File "/home/gblp250/PycharmProjects/practice/venv/local/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/home/gblp250/PycharmProjects/practice/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/home/gblp250/PycharmProjects/practice/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/gblp250/PycharmProjects/assignment/todoapp/views.py" in login_user
  48.             login_form.login_user(request)

File "/home/gblp250/PycharmProjects/assignment/todoapp/forms.py" in login_user
  27.             login(self, request, user)

File "/home/gblp250/PycharmProjects/practice/venv/local/lib/python2.7/site-packages/django/contrib/auth/__init__.py" in login
  126.     if SESSION_KEY in request.session:

Exception Type: AttributeError at /login/
Exception Value: 'Login' object has no attribute 'session'

参考方案

为此,您可以在窗体中覆盖is_valid方法(请参阅this link)并将逻辑放在此处,但是,更合适的方法是在视图中使用基于类的视图FormView并对其进行操作。

参考this link作为开始了解FormView通用基于类的方法。一旦您了解如何使用它,这将大大简化该过程。

编辑:

总体上看起来不错,但逻辑实现仍然有误

class Login(forms.Form):
    email = forms.EmailField(max_length=250)
    password = forms.CharField(widget=forms.PasswordInput)

    def login_user(self, request):
        email = self.cleaned_data['email']
        password = self.cleaned_data.get('password')
        user = authenticate(request, email=email, password=password)
        if user:
            login(request, user) // self should have been replaced by request
        else:
            return HttpResponseRedirect(reverse('view_task_list'))//You can redirect to any url

这是我的新views.py ::

def login_user(request):
    if request.method == 'POST':
        login_form = Login(request.POST)
        if login_form.is_valid():
            login_form.login_user(request) //just call the method created in the form
    else:
        login_form = Login() //this is for GET REQUEST
    return render(request, 'registration/login.html', {'form': login_form}) //you should return instance of the form

这是我的urls.py:

from django.conf.urls import url
from .import views

urlpatterns = [
    url(r'^index/', views.index, name='index'),
    url(r'^register/', views.register, name='register'),
    url(r'^login/', views.login_user, name='login_user'),
    url(r'^dashboard/', views.dashboard, name='dashboard'),
    url(r'^logout_user/', views.logout_user, name='logout_user'),
    url(r'^auth_users/', views.auth_users, name='auth_users'),
    # url(r'^authorize_final', views.authorize_final, name='authorize_final'),
    url(r'^assigntask', views.assigntask, name='assigntask'),
    # url(r'^assign', views.assign, name='assign'),
    url(r'^task_list', views.view_task_list, name='view_task_list'),
    # url(r'^delete_task', views.delete_task, name='delete_task'),
]

另外,由于使用默认的settings.py方法,因此必须在login()中设置登录和注销重定向URL。

LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/' //change as you wish

在返回'Response'(Python)中传递多个参数 - python

我在Angular工作,正在使用Http请求和响应。是否可以在“响应”中发送多个参数。角度文件:this.http.get("api/agent/applicationaware").subscribe((data:any)... python文件:def get(request): ... return Response(seriali…

为什么我无法更新字典中的test__user_id密钥? - python

我正在更新包含数据的字典,dict_temp = {'description': 'hello', 'id': 683, 'status': u'pending', 'test__user_id': 430} 我试图使用dict_temp …

Python exchangelib在子文件夹中读取邮件 - python

我想从Outlook邮箱的子文件夹中读取邮件。Inbox ├──myfolder 我可以使用account.inbox.all()阅读收件箱,但我想阅读myfolder中的邮件我尝试了此页面folder部分中的内容,但无法正确完成https://pypi.python.org/pypi/exchangelib/ 参考方案 您需要首先掌握Folder的myfo…

R'relaimpo'软件包的Python端口 - python

我需要计算Lindeman-Merenda-Gold(LMG)分数,以进行回归分析。我发现R语言的relaimpo包下有该文件。不幸的是,我对R没有任何经验。我检查了互联网,但找不到。这个程序包有python端口吗?如果不存在,是否可以通过python使用该包? python参考方案 最近,我遇到了pingouin库。

如何用'-'解析字符串到节点js本地脚本? - python

我正在使用本地节点js脚本来处理字符串。我陷入了将'-'字符串解析为本地节点js脚本的问题。render.js:#! /usr/bin/env -S node -r esm let argv = require('yargs') .usage('$0 [string]') .argv; console.log(argv…