9、Django实战第9天:用户注册功能
今天完成的是用户注册功能...
首先把注册页面的前端文件register.html复制到templates目录下
编辑users.views.py,创建一个注册的类
class RegisterView(View): def get(self, request): return render(request, 'register.html', {})
配置注册页面的url
... from users.views import LoginView, RegisterView urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^xadmin/', xadmin.site.urls), url(r'^$', TemplateView.as_view(template_name='index.html'), name='index'), url(r'^login/$', LoginView.as_view(), name='login'), url(r'register/$', RegisterView.as_view(), name='register'), ]
【新知识点--静态文件】替换注册页面的静态文件路径,这里我们不用之前的替换方法,而是使用Django提供的
【新知识点-url】修改首页index.html ‘注册’和‘登录’的超链接
【验证码】用户注册我们需要用到一个功能就是验证码
要使用验证码,就需要安装一个验证码开发库,这里我们使用django-simple-captcha
workon mxonline pip install django-simple-captcha
编辑settings.py添加captcha到INSTALLED_APPS
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'users', 'courses', 'organization', 'operation', 'xadmin', 'crispy_forms', 'captcha', ]
配置一条url
from django.conf.urls import url, include ... urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^xadmin/', xadmin.site.urls), url(r'^$', TemplateView.as_view(template_name='index.html'), name='index'), url(r'^login/$', LoginView.as_view(), name='login'), url(r'register/$', RegisterView.as_view(), name='register'), url(r'^captcha/', include('captcha.urls')), ]
同步数据表
manage.py@mxonline > makemigrations manage.py@mxonline > migrate
编辑users.forms.py配置表单验证
from captcha.fields import CaptchaField class RegisterForm(forms.Form): email = forms.EmailField(required=True) password = forms.CharField(required=True, min_length=5) captcha = CaptchaField()
编辑users.views.py
... from .forms import LoginForm, RegisterForm class RegisterView(View): def get(self, request): register_form = RegisterForm() return render(request, 'register.html', {'register_form': register_form})
修改register.html
启动服务,看看注册页面
查看数据库,可以发现验证码表已经生成了记录
继续写注册逻辑,当用户提交注册,对验证码进行验证。这里打个断点调试,故意输错验证码
可以看到错误信息"认证码错误", 我们也可以改成自己想要的信息(改成 验证码错误),编辑users.forms.py
class RegisterForm(forms.Form): email = forms.EmailField(required=True) password = forms.CharField(required=True, min_length=5) captcha = CaptchaField(error_messages={'invalid': '验证码错误'})
再次断点调试,已经变成我们自定义的信息了
继续注册流程编码
from django.contrib.auth.hashers import make_password class RegisterView(View): def get(self, request): register_form = RegisterForm() return render(request, 'register.html', {'register_form': register_form}) def post(self, request): register_form = RegisterForm(request.POST) if register_form.is_valid(): user_name = request.POST.get('email', '') pass_word = request.POST.get('password', '') user_profile = UserProfile() #实例化数据比哦啊 user_profile.username = user_name user_profile.email = user_name user_profile.password = make_password(pass_word) #对明文密码进行加密处理 user_profile.save() #保存到数据表 else: return render(request, 'register.html', {'register_form': register_form})
[邮箱激活]我们使用邮箱注册,就涉及到发送邮件激活
发送邮件需要发送者,我们需要再settings.py中配置(末尾添加如下代码)
EMAIL_HOST = 'smtp.sina.com' EMAIL_PORT = 25 EMAIL_HOST_USER = 'xxxx@sina.com' EMAIL_HOST_PASSWORD = 'xxxxx' EMAIL_USE_TLS = False EMAIL_FROM = xxxx@sina.com'
因此需要写一个邮件基础函数
在apps目录下新建一个Python Package命名为utils,把它专门用来存放一些基础函数
在utils下新建email_send.py
from random import Random from django.core.mail import send_mail from users.models import EmailVerifyRecord from mxonline.settings import EMAIL_FROM def random_str(randomlength=8): """生成随机字符""" str = '' chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789' length = len(chars) - 1 random = Random() for i in range(randomlength): str += chars[random.randint(0, length)] return str def sendEmail(email, send_type='register'): email_record = EmailVerifyRecord() code = random_str(16) email_record.code = code email_record.email = email email_record.send_type = send_type email_record.save() if send_type == 'register': email_title = '慕学在线网激活链接' email_body = '请点击下面的链接激活你的账号:http://127.0.0.1:8000/active/{0}'.format(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: pass
编辑注册后台逻辑,发送邮件
... from utils.email_send import sendEmail class RegisterView(View): def get(self, request): register_form = RegisterForm() return render(request, 'register.html', {'register_form': register_form}) def post(self, request): register_form = RegisterForm(request.POST) if register_form.is_valid(): user_name = request.POST.get('email', '') pass_word = request.POST.get('password', '') user_profile = UserProfile() #实例化数据比哦啊 user_profile.username = user_name user_profile.email = user_name user_profile.password = make_password(pass_word) #对明文密码进行加密处理 user_profile.is_active = False #处于未激活状态 user_profile.save() #保存到数据表 sendEmail(user_name, 'register') return render(request, 'login.html') else: return render(request, 'register.html', {'register_form': register_form})
下面可以进行注册调试了,进去注册页面用邮箱进行注册,去查看邮箱(如果没有,请注意垃圾箱)
查看数据库
如果邮箱和密码不满足条件,form验证失败了,我也和之前login一样,提示给用户,register.html
[用户未激活]
正常情况下,我们刚刚注册的账号没有激活是无法登陆的,所以下我们还需要修改下登录逻辑,只有激活后的账号才能登录
class LoginView(View): def get(self, request): return render(request, 'login.html', {}) def post(self, request): Login_form = LoginForm(request.POST) if Login_form.is_valid(): user_name = request.POST.get('username', '') pass_word = request.POST.get('password', '') user = authenticate(username=user_name, password=pass_word) if user is not None: if user.is_active: login(request, user) return render(request, 'index.html') else: return render(request, 'login.html', {'msg':'用户未激活'}) else: return render(request, 'login.html', {'msg': '用户名或密码错误'}) else: return render(request, 'login.html', {'login_form': Login_form})
现在再尝试用刚刚注册的账号登录,无法登陆成功,提示用户未激活
【账号激活】
现在来完成激活功能,编辑users.views.py,创建一个用于激活的类
class ActiveUserView(View): def get(self, request, active_code): #active_code是url传过来的参数 pass
配置url
... from users.views import LoginView, RegisterView, ActiveUserView urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^xadmin/', xadmin.site.urls), url(r'^$', TemplateView.as_view(template_name='index.html'), name='index'), url(r'^login/$', LoginView.as_view(), name='login'), url(r'register/$', RegisterView.as_view(), name='register'), url(r'^captcha/', include('captcha.urls')), url(r'^active/(?P<active_code>.*)/$', ActiveUserView.as_view(), name='user_active'), ]
现在断点调试,点击之前发送的激活邮件链接http://127.0.0.1:8000/active/04tMGcH7lPqsgG5G
active_code已经接收到了激活码,现在我们只需要把激活码取出来,然后去数据中查询,如果匹配上了,就把对应的用户激活
from .models import UserProfile, EmailVerifyRecord class ActiveUserView(View): def get(self, request, active_code): all_records = EmailVerifyRecord.objects.filter(code=active_code) if all_records: for record in all_records: email = record.email user = UserProfile.objects.get(email=email) user.is_active = True user.save() return render(request, 'login.html')
现在点击激活链接,就可以激活成功,跳转登录页面,然后账号就可以成功登录了