Django网站建设-用户注册、登陆、邮箱激活、密码找回

Django URL name详解(运用相对路径,修改匹配正则后可减少修改量)

Django URL name详解

将Temlate中所有的修改为相对路径url

注册
登录

将所有的静态文件修改为相对路径staticfile(前提在setting中设置好STATIC_URL 和STATICFILES_DIRS才能找到路径)

以后所有写成相对路径

#模板中添加声明
{% load staticfiles %}

#添加方法,如此以来,即使修改了static的路径也不会修改,因为引用的是相对路径



安装Django-simple-captcha,用于生成验证码。

下载连接-github

文档说明

Installation
1、Install django-simple-captcha via pip: pip install django-simple-captcha
2、Add captcha to the INSTALLED_APPS in your settings.py
3、Run python manage.py migrate
4、Add an entry to your urls.py:

urlpatterns += [
    url(r'^captcha/', include('captcha.urls')),
]

添加验证吗

在app.form中建立register_form表单,定义好注册需要的字段(form可自动生成input框)【form实现了后台与前端的交互】

class RegisterForm(forms.Form):
    Email = forms.EmailField(required=True)
    Password = forms.CharField(required=True,min_length=5)
    captcha = CaptchaField()

将form加入RegisterView视图中,并将form数据传入Template中

class RegisterView(View):
    def get(self,request):
        register_form = RegisterForm()
        return render(request,'register.html',{'register_form':register_form})  #将register_form数据传递给Template

通过Template将register_form传入html中,生成验证码(form数据可通过Template自动生成input框)

{{ register_form.captcha }}

完成注册的后台逻辑,get方法用于刷新,post方法用于接受用户信息并进行存储

class RegisterView(View):
    def get(self,request):
        register_form = RegisterForm()
        return render(request,'register.html',{'register_form':register_form})  #将register_form数据传递给Template
    def post(self, request):
        register_form = RegisterForm(request.POST)  #将post上来的数据传递给RegisterForm
        if register_form.is_valid():    #上传的数据符合form表要求,有效
            user_name = request.POST.get('username','')
             if UserProfile.objects.filter(email=user_name):
            return render(request, 'register.html', {'register_form':register_form,'msg': '用户已存在'})  # 该逻辑用户判断用户是否已注册存在
            pass_word = request.POST.get('password','')
            user_profile = UserProfile()
            user_profile.username = user_name
            user_profile.email = user_name
            #明文数据需要经过加密后传入数据库,利用make_password方法加密
            user_profile.password = make_password(pass_word)
            user_profile.save()
        else:
            return render(request, 'register.html', {'register_form': register_form})  # 将register_form数据传递给Template

注意html中相同的、多余的input会影响文本输出

将value传回Template中



通过邮箱发送验证链接进行注册激活

Django 使用 QQ / 新浪邮箱发送邮件配置

创建utils文件夹,用于存放工具函数/类

from users.models import EmailVerifyCode
from random import Random
from django.core.mail import send_mail
from GMOOC.settings import EMAIL_HOST,EMAIL_PORT,EMAIL_HOST_USER,EMAIL_HOST_PASSWORD,EMAIL_USE_TLS,EMAIL_FROM

用于生成随机生成验证吗,长度可调

#随机生成验证吗,长度可调
def random_str(random_length=8):
    code = ''
    chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'
    random = Random()
    length = len(chars)-1
    for i in random_length:
        code += chars[random.randint(0,length)]
    return code

用于生成随机验证码和对应的邮箱并存入数据库中,将验证码以链接形式发送至邮箱,点击进行激活

def send_register_email(email, send_type='register'):
    ###########################生成随机验证码存入数据库中###########################
    #继承模型
    email_record = EmailVerifyCode()
    code = random_str(16)
    #将随机生成code存入数据库中
    email_record.code = code
    #将管理的邮箱传入数据库中
    email_record.email = email
    #定义发送类型
    email_record.send_type = send_type
    email_record.save()

    ###########################发送激活邮件###########################
    email_title = ''
    email_body = ''
    receive_email = email

    if send_type == 'register':
        email_title = '慕学在线激活连接'
        email_body = '请点击下方连接,激活注册:'+'http://127.0.0.1:8000/active/{0}'.format(code)

    if send_type =='find_password':
        email_title = '慕学在线密码找回连接'
        email_body = '请点击下方连接,进行密码找回:' + 'http://127.0.0.1:8000/active/{0}'.format(code)

    send_status = send_mail(email_title, email_body, EMAIL_FROM, [receive_email])

将注册页上传上来的信息保存值UserProfile,但是is_active还是0,表示还未进行激活。完成注册后跳转至登陆页面,注册失败的仍停留在注册页

class RegisterView(View):
    def get(self,request):
        register_form = RegisterForm()
        return render(request,'register.html',{'register_form':register_form})  #将register_form数据传递给Template
        #return render(request,'register.html',{})
    def post(self, request):
        register_form = RegisterForm(request.POST)  #将post上来的数据传递给RegisterForm
        if register_form.is_valid():    #上传的数据符合form表要求,有效
            user_name = request.POST.get('email','')
            pass_word = request.POST.get('password','')
            ########注册的时候需要查看邮箱是否有重复,利用了username进行了去重#######
            user_profile = UserProfile()
            user_profile.username = user_name
            user_profile.email = user_name
            #明文数据需要经过加密后传入数据库,利用make_password方法加密
            user_profile.password = make_password(pass_word)
            user_profile.is_active = 0  #表面用户还未激活
            user_profile.save()
            #用于邮件激活操作
            send_register_email(user_name, send_type='register')
            return render(request, 'login.html', {})  # 将register_form数据传递给Template
        else:
            #注册失败跳转至index页面,暂时
            #return render(request,'index.html',{})
            return render(request, 'register.html', {'register_form':register_form})  # 将register_form数据传递给Template

在url中,通过(?P.*)正则获取获取匹配的字符串(实际就是发送的验证码),绑定ActiveUserView,通过该类完成激活

    url(r'^active/(?P.*)/$',ActiveUserView.as_view(),name='active_user')

ActiveUserView原理就是通过get,获取激活的请求,通过验证码在EmailVerifyCode中查询到对应的邮箱,通过邮箱在UserProfile查询到对应的账号信息,并将is_active 变为1,即完成激活

class ActiveUserView(View):
    def get(self,request,active_code): #利用code在EmailVerifyCode进行查询
        EmailVerifyCodeRecorder = EmailVerifyCode.objects.filter(code=active_code)
        if EmailVerifyCodeRecorder:
            #找到UserProfile中的对应账号,并设is_active为1,即为激活账号
            for i in EmailVerifyCodeRecorder:
                email = i.email
                user = UserProfile.objects.get(email=email)
                user.is_active = 1
                user.save()
                return render(request, 'login.html', {})  # 将register_form数据传递给Template
        else:
            return render(request, 'active_fail.html', {})  #找不到记录则返回连接失效的页面

密码找回

在Template中设置忘记密码的跳转

忘记密码?

在url中定义forgetpwd页面

url(r'^forgetpwd/$', ForgetpwdView.as_view(), name='forgetpwd'),

定义ForgetpwdForm

class ForgetpwdForm(forms.Form):
    email = forms.EmailField(required=True)
    captcha = CaptchaField(error_messages={'invalid':u'验证码错误'})

将form的验证码form传入html中,并配置好静态文件

#html中配置验证码
{{ forgetpwd_form.captcha }}

发送邮箱的函数

def send_email(email, send_type='register'):
    ###########################生成随机验证码存入数据库中###########################
    #继承模型
    email_record = EmailVerifyCode()
    code = random_str(16)
    #将随机生成code存入数据库中
    email_record.code = code
    #将管理的邮箱传入数据库中
    email_record.email = email
    #定义发送类型
    email_record.send_type = send_type
    email_record.save()

    ###########################发送激活邮件###########################
    email_title = ''
    email_body = ''
    receive_email = email

    if send_type == 'register':
        email_title = '慕学在线激活连接'
        email_body = '请点击下方连接,激活注册:'+'http://127.0.0.1:8000/active/{0}'.format(code)

    if send_type =='find_password':
        email_title = '慕学在线密码找回连接'
        email_body = '请点击下方连接,进行密码找回:' + 'http://127.0.0.1:8000/password_reset/{0}'.format(code)

    send_status = send_mail(email_title, email_body, EMAIL_FROM, [receive_email])

在view中定义ForgetpwdView后台逻辑

class ForgetpwdView(View):
    def get(self,request):
        forgetpwd_form = ForgetpwdForm()
        return render(request,'forgetpwd.html',{'forgetpwd_form':forgetpwd_form})    #将验证码传递给前端

    def post(self,request):
        forgetpwd_form = ForgetpwdForm(request.POST)
        if forgetpwd_form.is_valid():
            #post数据成功,将验证码保存在EmailVerifyCode,用于激活查询,并跳转至index页面
            email = request.POST.get('email')
            send_email(email, send_type='find_password')
            return render(request,'index.html',{})
        else:
            #验证码错误或邮箱格式错误返回信息
            return render(request,'forgetpwd.html',{'forgetpwd_form':forgetpwd_form})

注意form表单的变量名称要与html中的name保持一直, forgetpwd_form = ForgetpwdForm(request.POST)才能匹配

编写修改密码连接的url,绑定PasswordReset

url(r'^password_reset/(?P.*)/$', PasswordReset.as_view(), name='password_reset'),

编写修改密码的后台逻辑

打开连接,后台自动获取相对唯一的active_code,通过active_code在EmailVerifyCode中找到对应的email,通过email在UserProfile中找到对应的用户信息,符合条件则修改用户密码。

class PasswordReset(View):
    def get(self,request,active_code):
        return render(request,'password_reset.html',{}) #获取修改密码页面
    def post(self,request,active_code):
        EmailVerifyCodeRecorder = EmailVerifyCode.objects.filter(code=active_code)  #通过active_code去EmailVerifyCode找到对应的email
        if EmailVerifyCodeRecorder: #如果该验证码存在
            # 找到UserProfile中的对应账号,进行修改密码
            for i in EmailVerifyCodeRecorder:   #一般来说该验证码是唯一的
                email = i.email #找到email
                user = UserProfile.objects.get(email=email) #通过email在UserProfile中找到对应的用户数据
                password_reset = PasswordResetForm(request.POST)    #新密码上传至表单中
                if password_reset.is_valid():   #新设置的密码符合表单的话
                    password = request.POST.get('password','')
                    password2 = request.POST.get('password2','')
                    if password == password2: #两个密码相同,所有逻辑正确,进行密码修改
                        #在数据库中信息密码修改
                        user.password = make_password(password)
                        user.save()
                        return render(request, 'login.html', {})  # 将register_form数据传递给Template
                    else:   #如果两个密码不相同
                        return render(request, 'password_reset.html', {'msg':'两个密码不一致'})  # 将register_form数据传递给Template
                else:   #表单验证不通过
                    return render(request, 'password_reset.html', {'msg':'密码未填写或格式有问题'})
        else:
            pass    #返回404页面

Template的修改

1.静态文件配置:{% static 'name' %}
2.url的配置:{% url 'name' %}
3.错误信息提示:
{% for key,error in forgetpwd_form.errors.items %}{{ error }}{% endfor %}
4.错误信息聚焦:
5.值回填

用户退出

用户退出

前端配置“注销按钮”的触发逻辑:单机“退出”跳转至user_loginout的url中

退出

在url中定义好视图逻辑

url(r'^loginout/$', logout_view, name='user_loginout'),

在view中定义好logout_view函数的逻辑,利用系统logout函数清除request的登陆信息

from django.contrib.auth import authenticate,login,logout
def logout_view(request):
    logout(request)
    return render(request, 'index.html', {})  # 登陆成功,由后台渲染跳转至index,并在index中判断,头部显示

你可能感兴趣的:(django)