day061 Django之form组件和用户认证组件

本节内容:

1、form组件(校验字段的功能)
2、用户认证组件

一、form组件(校验字段的功能)

在views.py下创建一个对应该表的类,规定输入字段的规则

1、四条语法

ef = EmpForm({"name":"shuying", "age":20}) # 实例化一个form对象,传的实参为一个字典,
#           为你要校验的字段,注意键名要跟类变量的名一致

ef.is_valid() # 检验字段,是否符合规则
ef.cleaned_data # 拿到干净的数据
ef.errors  # 拿到错误的信息,样式为字典:{'name': ['This field is required.']}
语法演示
# 在views.py文件下
from django import forms # forms组件

class EmpForm(forms.Form): # 通过创建一个类,来限定输入字段规则 name=forms.CharField(min_length=5) age=forms.IntegerField() # Django控制台查看 from app01.models import EmpForm Traceback (most recent call last): File "<input>", line 1, in <module> ImportError: cannot import name 'EmpForm' from app01.views import EmpForm ef=EmpForm({"name":"yuan","age":23}) # 示例一个form对象,传参为一个字典 ef.is_valid() # 检验字段,是否符合规则 False ef=EmpForm({"name":"yuan123","age":23}) ef.is_valid() True ef=EmpForm({"name":"yuan123","age":23,"a":1}) # 传参字段多了,没有问题,不影响校验结果, ef.is_valid() True ef=EmpForm({"names":"yuan123","age":23,"a":1}) # 校验的传入的实参键值对的键名要和form类使用的类属性的名一致 ef.is_valid() # 校验只要有一项不符合规则,就报错不通过,类似于事务 False ef.cleaned_data # 获取干净的数据 {'age': 23} ef.errors # 获取错误的数据 {'name': ['This field is required.']} 
Python

2、作用之校验数据(重点)

通过创建一个类,该类继承forms.Form类,
就可以通过其来起到校验数据的作用
class EmpForm(forms.Form): # 限制字段的条件,校验数据 name=forms.CharField(min_length=5,label="姓名",error_messages={"required":"该字段不能为空!"}) # 返回对应错误的提示 age=forms.IntegerField(label="年龄") salary=forms.CharField(label="薪水") 
Python

3、作用之渲染模板(add.html)

1 代码简单
2 命名规范
3 显示错误信息  # 方便显示,可以直接在模板中调用

1、渲染方式一(常用)

用for循环取出每一个字段,
<h3>渲染方式3</h3> <form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} {# for循环取出每一个字段 #} <div> <label for="">{{ field.label }}</label> {{ field }} <span>{{ field.errors.0 }}</span> {# 错误信息直接点出来 #} </div> {% endfor %} <input type="submit" value="submit"> </form> 
HTML

2、渲染方式二

单独写每一个标签
<h3>渲染方式2 </h3> <form action="" method="post" novalidate> {% csrf_token %} <div> <label for="">姓名</label> {{ form.name }} <span>{{ form.name.errors.0 }}</span> </div> <div> <label for="">年龄</label> {{ form.age }}<span>{{ form.age.errors.0 }}</span> </div> <div> <label for="">薪水</label> {{ form.salary }}<span>{{ form.salary.errors.0 }}</span> </div> <input type="submit" value="submit"> </form> 
HTML

3、渲染方式三

自动生成,键名为类属性的名
<h3>渲染方式1 </h3> <form action="" method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="submit"> </form> 
HTML

4、显示错误与重置输入信息功能

利用form表单刷新页面,显示用户输入的错误原因

视图函数

def addEmp(request): if request.method=="GET": form=EmpForm() # 实例一个form组件对象 return render(request,"add.html",locals()) else: # print(request.POST) form=EmpForm(request.POST) if form.is_valid(): # 执行校验字段 # print(form.cleaned_data) # print(form.errors) Emp.objects.create(**form.cleaned_data) # 所有的校验成功后,这里将数据添加进数据库,为该表格增加一条记录 return HttpResponse("添加成功") else: # print(form.cleaned_data) # print(form.errors) # 错误的存储方式为: {"name":["Ensure this value has at least 5 characters (it has 3).",]} return render(request, "add.html",{"form":form}) 
Python

模板

<h3>渲染方式3</h3> <form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div> <label for="">{{ field.label }}</label> {{ field }} <span>{{ field.errors.0 }}</span> </div> {% endfor %} <input type="submit" value="submit"> </form> 
HTML

5、钩子:灵活制定各种校验规则

针对字段的,你写一个方法,检验一个字段,执行详细的检验规则,
方法名要按规定写。def clear_类属性名():

视图中的钩子

    #  钩子,灵活定制的校验规则
    def clean_name(self): # 方法名固定写法,详细要求字段的规则 val=self.cleaned_data.get("name") # 二次校验 if val.isdigit(): # 校验是否是纯数字 raise ValidationError("姓名不能是纯数字!") # 根据校验规则,提示错误信息 elif Emp.objects.filter(name=val): # 检验是否在数据库已存在 raise ValidationError("该员工已存在!") else: return val # 必须把这个值返回 def clean_age(self): val=self.cleaned_data.get("age") if int(val) > 100: raise ValidationError("年龄不能大于100!") else: return val 
Python

6、基于ajax请求的信息校验(重点)

视图

from django.http import JsonResponse

def addEmp(request): if request.is_ajax(): # 判断是否是ajax请求,判断是post请求也可以,只要不是GET请求,就执行验证逻辑 form = EmpForm(request.POST) # 实例化一个form对象,用于校验 res={"state":True,"errors":None} if form.is_valid(): # 进行校验 Emp.objects.create(**form.cleaned_data) # 全部成功添加进数据库 else: res["state"]=False res["errors"]=form.errors # 收集错误信息 return JsonResponse(res) else: form = EmpForm() return render(request, "add.html", locals()) 
Python

模板中的HTML文件,ajax请求

<h3>Ajax提交</h3> <form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div> <label for="">{{ field.label }}</label> {{ field }} <span class="error"></span> </div> {% endfor %} <input type="button" class="ajax_btn" value="submit"> </form> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script> (".ajax_btn").click(function () { .ajax({ url:"", {# 不写就是默认当前地址重新发送 #} type:"post", data:{ "name":("#id_name").val(), "age":("#id_age").val(), "salary":("#id_salary").val(), csrfmiddlewaretoken:("[name='csrfmiddlewaretoken']").val() }, success:function (res) { console.log(res); if (res.state){ console.log("添加成功!") }else{ // 清空操作 ("span.error").html(""); {# 清空上一次的错误信息 #} // 循环显示错误信息 .each(res.errors,function (key,value) { console.log(key,value[0]); $("#id_"+key).next().html(value[0]) }) } } }) }) </script> 
HTML

二、用户认证组件

Django自带的方便我们进行用户认证的组件,所有的request都会经过这个中间件

大前提:
这里使用的所有的API函数针对的是Django自带的auth_user表。

1、auth模块

auth模块提供功能:

1 大前提:API函数针对的是django自带的auth_user----- 这个表是Django自带的,我们直接用,创建记录用命令创建 2 为django下auth_user表创建用户: # 用命令创建,不要在表里直接输入 python manage.py createsuperuser 3 # user_obj=UserInfo.objects.filter(name=user,pwd=pwd).first() user_obj=auth.authenticate(username=user,password=pwd) # 查询有该对象,则返回对象(即校验用户名和密码),否则返回None # authenticate 4 auth.login(request,user_obj) # 1 注入session信息: # request.session["user_id"]=user_obj.pk # 下次用户再访问时就带着这个,经过中间件就会赋予代表其登录成功的状态,而不用再次登录 # 2 request.user=user_obj # 补充 request.user: (1) 之前函数执行login(),登录成功,request.user代表登录对象 (2) AnonymousUser默认匿名用户对象, request.user.id request.user.username 5 auth.logout(request) # 注销当前用户的方法 auth user对象的API: request.user.id request.user.is_authenticated() 6 @login_required # 用户认证组件自带的检验用户是否登录的装饰器 7 创建用户 auth_user表:from django.contrib.auth.models import User User.objects.create(username="alex",password="123") User.objects.create_user(username="alex",password="123") User.objects.create_superuser(username="alex",password="123") 
Python
实例详解
from django.contrib import auth # 引入自带的auth模块


def login(request): if request.method=="GET": # get请求获取登录页面 return render(request,"login.html") else: user = request.POST.get("user") pwd = request.POST.get("pwd") # user_obj=UserInfo.objects.filter(name=user,pwd=pwd).first() user_obj=auth.authenticate(username=user,password=pwd) # 查询有该对象,则返回对象,否则返回None if user_obj: # request.session["is_login"]=True # request.session["username"]=user # session方法的操作对比来看用户认证组件 auth.login(request,user_obj) # 注入session信息: # request.session["user_id"]=user_obj.pk print(">>>>",request.user) print(request.path) print(request.get_full_path()) print(request.GET.get("next")) # 拿到next的对应的路径,就是你在哪个页面点进来,登录成功后,返回那个页面 path=request.GET.get("next") or "/index/" # 通过简单的逻辑运算,如果是直接从登录页面进来的,就返回首页 return redirect(path) return redirect("/login/") from django.contrib.auth.decorators import login_required @login_required # 用户认证组件自带的检验用户是否登录的装饰器,功能跟注释的代码一样 def index(request): # if not request.user.id: # return redirect("/login/") # print(request.user) # 当前登录用户 return render(request,"index.html",locals()) @login_required def order(request): # 查看 # if not request.user.id: # return redirect("/login/") # print(request.user) # 当前登录用户 return render(request,"order.html") def logout(request): auth.logout(request) # 注销当前用户的方法 return redirect("/login/") 
Python

1、auth模块命令解析

from django.contrib import auth
django.contrib.auth中提供了许多方法,这里主要介绍其中的三个:

1、authenticate()

提供了用户认证,即验证用户名以及密码是否正确,一般需要username  password两个关键字参数

如果认证信息有效,会返回一个User 对象。
authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,
且该信息在后面的登录过程中是需要的。
当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的!!

user = authenticate(username='someone',password='somepassword')

2、login(HttpRequest, user)

该函数接受一个HttpRequest对象,以及一个认证了的User对象

此函数使用django的session框架给某个已认证的用户附加上session id等信息。
from django.contrib.auth import authenticate, login def my_view(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None: login(request, user) # 注入session信息: # request.session["user_id"]=user_obj.pk # Redirect to a success page. ... else: # Return an 'invalid login' error message. ... 
Python

3、logout(request) 注销用户

该函数接受一个HttpRequest对象,无返回值。
当调用该函数时,当前请求的session信息会全部清除。

该用户即使没有登录,使用该函数也不会报错。
from django.contrib.auth import logout

def logout_view(request):
  logout(request)
Pyhton

2、user对象的 is_authenticated()

User 对象属性:username, password(必填项)password用哈希算法保存到数据库

1、user对象的 is_authenticated()

如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。

通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,
这只是表明用户成功的通过了认证。

这个方法很重要, 在后台用request.user.is_authenticated()判断用户是否已经登录,
如果true则可以向前台展示request.user.name

fe:要求

要求:

1  用户登陆后才能访问某些页面,

2  如果用户没有登录就访问该页面的话直接跳到登录页面

3  用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址

方法1: 自己写逻辑 def my_view(request): if not request.user.is_authenticated(): return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path)) 方法2: django已经为我们设计好了一个用于此种情况的装饰器:login_requierd() from django.contrib.auth.decorators import login_required @login_required def my_view(request): ... 若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' ( 这个值可以在settings文件中通过LOGIN_URL进行修改)。 并传递 当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。 
Python

2、创建用户

使用 create_user 辅助函数创建用户:

from django.contrib.auth.models import User
user = User.objects.create_user(username='',password='',email='')

3、check_password(passwd)

用户需要修改密码的时候 首先要让他输入原来的密码 ,
如果给定的字符串通过了密码检查,返回 True

4、修改密码

使用 set_password() 来修改密码

user = User.objects.get(username='')
user.set_password(password='')
user.save 

3、简单示例

1、注册

注册简单示例
def sign_up(request): state = None if request.method == 'POST': password = request.POST.get('password', '') repeat_password = request.POST.get('repeat_password', '') email=request.POST.get('email', '') username = request.POST.get('username', '') if User.objects.filter(username=username): state = 'user_exist' else: new_user = User.objects.create_user(username=username, password=password,email=email) new_user.save() return redirect('/book/') content = { 'state': state, 'user': None, } return render(request, 'sign_up.html', content)  
Python

1、修改密码

修改密码简单示例
@login_required
def set_password(request): user = request.user state = None if request.method == 'POST': old_password = request.POST.get('old_password', '') new_password = request.POST.get('new_password', '') repeat_password = request.POST.get('repeat_password', '') if user.check_password(old_password): if not new_password: state = 'empty' elif new_password != repeat_password: state = 'repeat_error' else: user.set_password(new_password) user.save() return redirect("/log_in/") else: state = 'password_error' content = { 'user': user, 'state': state, } return render(request, 'set_password.html', content) 
 

猜你喜欢

转载自www.cnblogs.com/yipianshuying/p/10278454.html
今日推荐