Django工程的分层结构 (3)

execute函数会执行valid_data()函数,如果执行成功我才会向下执行,可是你看我在execute函数中并没有这样的语句,比如:

def execute(self): if self.valid_data(): user_account = self._factory_user_account() self._send_welcome_email_to(user_account) return user_account else: pass

换句话说你的每个函数都可能有返回值,如果每一个你都这样写代码就太啰嗦了。其实你可以看到在valid_data函数中我的确返回了True,但是我希望你也应该注意,如果用户存在的话我并没有返回False,而是raise一个异常,这样这个异常就会被调用方获取而且还能获取错误信息,这种方式将是一个很好的处理方式,具体你可以通过views.py中看到。

Forms表单验证

这里是对于用户输入做检查

""" 表单验证功能 """ from django import forms from django.utils.translation import gettext as _ class RegisterAccountForm(forms.Form): username = forms.CharField(max_length=50, required=True, error_messages={ 'max_length': '用户名不能超过50个字符', 'required': '用户名不能为空', }) email = forms.EmailField(required=True) password = forms.CharField(min_length=6, max_length=20, required=True, widget=forms.PasswordInput()) confirm_password = forms.CharField(min_length=6, max_length=20, required=True, widget=forms.PasswordInput()) def clean_confirm_password(self) -> str: # -> str 表示的含义是函数返回值类型是str,在打印函数annotation的时候回显示。 """ clean_XXXX XXXX是字段名 比如这个方法是判断两次密码是否一致,密码框输入的密码就算符合规则但是也不代表两个密码一致,所以需要自己来进行检测 :return: """ password = self.cleaned_data.get('password') confirm_password = self.cleaned_data.get('confirm_password') if confirm_password != password: raise forms.ValidationError(message='Password and confirmation do not match each other') return confirm_password

前端可以实现输入验证,但是也很容易被跳过,所以后端肯定也需要进行操作,当然我这里并没有做预防XSS攻击的措施,因为这个不是我们今天要讨论的主要内容。

Views from django.shortcuts import render, HttpResponse, HttpResponseRedirect from rest_framework.views import APIView from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode from django.utils.encoding import force_bytes, force_text from .forms import ( RegisterAccountForm, ) from .services import ( RegisterUserAccount, UsernameAlreadyExistError, ActivateUserAccount, ActivatitionTokenError, UserIdIsNotExistError, ) # Create your views here. class Register(APIView): def get(self, request): return render(request, 'register.html') def post(self, request): # print("request.data 的内容: ", request.data) # print("request.POST 的内容: ", request.POST) # 针对数据输入做检查,是否符合规则 ra_form = RegisterAccountForm(request.POST) if ra_form.is_valid(): # print("验证过的数据:", ra_form.cleaned_data) rua = RegisterUserAccount(request=request, **ra_form.cleaned_data) try: rua.execute() except UsernameAlreadyExistError as err: # 这里就是捕获自定义异常,并给form对象添加一个错误信息,并通过模板渲染然后返回前端页面 ra_form.add_error('username', str(err)) return render(request, 'register.html', {'info': ra_form.errors}) return HttpResponse('We have sent you an email, please confirm your email address to complete registration') # return HttpResponseRedirect("/account/login/") else: return render(request, 'register.html', {'info': ra_form.errors}) class Login(APIView): def get(self, request): return render(request, 'login.html') def post(self, request): print("request.data 的内容: ", request.data) print("request.POST 的内容: ", request.POST) pass class ActivateAccount(APIView): # 用户激活账户 def get(self, request, uidb64, token): try: # 获取URL中的用户ID uid = force_bytes(urlsafe_base64_decode(uidb64)) # 激活用户 aua = ActivateUserAccount(uid, token) aua.execute() return render(request, 'login.html') except(ActivatitionTokenError, UserIdIsNotExistError) as err: return HttpResponse('Activation is failed.')

这里就是视图层不同URL由不同的类来处理,这里只做基本的接收输入和返回输出功能,至于接收到的输入该如何处理则有其他组件来完成,针对输入格式规范则由forms中的类来处理,针对数据验证过后的具体业务逻辑则由services中的类来处理。

Urls from django.urls import path, re_path, include from .views import ( Register, Login, ActivateAccount, ) app_name = 'users' urlpatterns = [ re_path(r'^register/$', Register.as_view(),), re_path(r'^login/$', Login.as_view(),), re_path(r'^activate/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', ActivateAccount.as_view(),), ] Templates

是我用到的html模板,我就不放在这里了,大家可以去这里https://files.cnblogs.com/files/rexcheny/mysite.zip

下载全部的代码

页面效果

Django工程的分层结构

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppysp.html