使用Django自带的用户认证系统编写认证、登录、注销基本功能
功能:
使用Django默认的User表
1)注册
判断是否已存在此用户,存在的话提示报错“用户已存在”;
判断两次输入的密码是否一致,不一致的话提示报错“密码不一致”。
实现报错提示的方式有两种:
第一种:在form表单中使用clean_函数进行定义判断函数,在views中进行的is_valid()判断时进行校验,并获取错误传送到模板中显示在前端。
第二种:直接在views视图中判断
2)登录
登录成功,跳转到主页index;
登录不成功,初始化登录页面;
跳转到注册页面。
3)主页
直接访问主页,用户没有登录的话跳转到登录页面;
用户已登录显示用户登录名。
4)注销
清除登录的session,退出登录
项目目录结构:
mysite/setting设置
注册应用:
更改时区和语言设置
from django.contrib import admin from django.urls import path from django.conf.urls import url,include urlpatterns = [path('admin/', admin.site.urls),url(r'^djauth/',include('djauth.urls',namespace='djauth')),]
from django.urls import re_path from . import views app_name='djauth' urlpatterns=[re_path(r'^$',views.index),re_path(r'register/$',views.register,name="register"),re_path(r'login/$',views.login_view,name="login"),re_path(r'logout/$',views.logout_view,name="logout"), ]
from django import forms from django.contrib.auth.models import User class login_form(forms.Form):username=forms.CharField(max_length=30)password=forms.CharField(widget=forms.PasswordInput)class register_form(forms.Form):username=forms.CharField(max_length=30,label="姓名")email=forms.EmailField()password=forms.CharField(widget=forms.PasswordInput,min_length=3,label="密码")password_re=forms.CharField(widget=forms.PasswordInput,min_length=3,label="确认密码")#第一种报错方式,使用form表单,views中捕捉##clean_字段,,在视图views使用is_valid时自动严重表单字段的有效性# def clean_username(self):# cd=self.cleaned_data# user=User.objects.filter(username=cd['username'])# if user:# raise forms.ValidationError('用户已存在')# return cd['username']# def clean_password_re(self):# cd=self.cleaned_data# if cd['password']!=cd['password_re']:# raise forms.ValidationError("密码不一致")# return cd['password_re']
from django.shortcuts import render,redirect,reverse from django.http import HttpResponse import time from django.contrib import auth from django.contrib.auth.models import User from . import forms#访问index首页前先判断用户是否登录,没有登录的话需要跳转到login登录 #实现方式一:判断request.user.is_authenticated # def index(request): # #验证用户是否登录成功 # if request.user.is_authenticated: # # request.user.username;;获取登录用户名 # print("UserAuth:",request.user.username) # return render(request,"djauth/index.html") # else: # return redirect("/djauth/login/") #实现方式二:使用@login_required装饰器 #login_required装饰器会先判断用户是否登录,如果没有登录则自动跳转到login_url路径, #默认跳转路径是/accounts/login/,并在登录后跳转到原先的请求路径;如请求路径/djauth、, #默认跳转路径为/accounts/login/?next=/djauth/#示例: #没有login_url #[13/Dec/2018 14:40:16] "GET /djauth/ HTTP/1.1" 302 0 #302跳转 #[13/Dec/2018 14:40:16] "GET /accounts/login/?next=/djauth/ HTTP/1.1" #指定loging_url #[13/Dec/2018 14:41:31] "GET /djauth/ HTTP/1.1" 302 0 #[13/Dec/2018 14:41:32] "GET /djauth/login/?next=/djauth/ HTTP/1.1" 200 725 #[13/Dec/2018 14:42:35] "POST /djauth/login/?next=/djauth/ HTTP/1.1" 302 0 #302登录成功后自动跳转 #[13/Dec/2018 14:42:35] "GET /djauth/ HTTP/1.1" 200 263 from django.contrib.auth.decorators import login_required @login_required(login_url="/djauth/login/") def index(request):return render(request,"djauth/index.html")def register(request):errors=[]if request.method=='POST':#初始化表单RegisterForm=forms.register_form(request.POST)#验证表单的输入是否有效,格式是否正确if RegisterForm.is_valid():# 第一种报错方式,捕捉form表单的报错##获取表单有效的值# Register=RegisterForm.cleaned_data##创建用户# user=User.objects.create_user(username=Register['username'],# password=Register['password'],# email=Register['email']# )##保存# user.save()# return HttpResponse("注册成功")##获取form表单clean函数中raise的错误#errors=RegisterForm.errors#第二种报错方式,直接在views中判断Register=RegisterForm.cleaned_data#判断用户是否存在user_exist=User.objects.filter(username=Register['username']).exists()if user_exist:errors.append("用户已存在")if Register['password']!=Register['password_re']:errors.append("密码不一致")else:user=User.objects.create_user(username=Register['username'],password=Register['password'],email=Register['email'])user.save()return HttpResponse("注册成功")#初始化表单RegisterForm=forms.register_form()return render(request,"djauth/register.html",{"RegisterForm":RegisterForm,"errors":errors})def login_view(request):error=[]curtime=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())if request.method=='POST':LoginForm=forms.login_form(request.POST)if LoginForm.is_valid():Account=LoginForm.cleaned_data#验证User表中用户的账号密码是否正确,验证通过,返回用户名,不通过,返回Noneuser=auth.authenticate(username=Account['username'],password=Account['password'])if user is not None:#判断账户是否活跃if user.is_active:auth.login(request,user)return redirect("/djauth/")else:error.append("用户无效")else:error.append("账号或密码错误")else:LoginForm=forms.login_form()return render(request,'djauth/login.html',{"LoginForm":LoginForm,"curtime":curtime,"error":error})def logout_view(request):#清除session,登出 auth.logout(request)return redirect("/djauth/login")
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>{% block title %}{% endblock %}</title> </head> <body> {% block content %}{% endblock %} </body> </html>
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>首页</title> </head> <body> <h1>首页</h1> <!--获取登录用户名:request.user.username或user.username--> {% if request.user.is_authenticated %}{{ user.username }} {% endif %}<p><a href="{% url 'djauth:logout' %}">退出</a></p> </body> </html>
{% extends "djauth/base.html" %}{% block title %} Login Page {% endblock %}{% block content %} <h1>Login Page</h1>{% if error %}{{ error }}{% endif %}<p>时间:{{ curtime }}</p><form action="" method="post">{% csrf_token %}{{ LoginForm.as_p }}<input type="submit" value="Login"></form><p>没有账号?点击<a href="{% url 'djauth:register' %}">注册</a></p> {% endblock %}
{% extends "djauth/base.html" %} {% block title %} Register Page {% endblock %}{% block content %} <h1>Register Page</h1>{% if errors %}<p>{{ errors }}</p>{% endif %}<form action="" method="post">{% csrf_token %}{% for foo in RegisterForm %}<p>{{ foo.label_tag }}{{ foo }} {{ errors.foo }}</p>{% endfor %}<input type="submit" value="注册"></form> {% endblock %}