django实现登录和登录的鉴权

1、创建数据库的管理员表

在models.py 中定义admin表,为了简单,表里只有用户名和密码还有默认加的id 三个字段

from django.db import models

# Create your models here.

class Admin(models.Model):
    username = models.CharField(verbose_name="用户名",max_length=16)
    passwd = models.CharField(verbose_name="密码",max_length=64)

执行创建表的语句

py -3 manage.py makemigrations
py -3 manage.py migrate

然后自己手动插入一些用户

2、登录界面和登录视图

在urls.py中加入路径

from django.urls import path
from app01.views import user,depart,pretty,admin,account

urlpatterns = [
    #path('admin/', admin.site.urls),
    path('depart/list/', depart.depart_list),
    path('depart/add/', depart.depart_add),
    path('depart/delete/', depart.depart_delete),
    #http://127.0.0.1:8000/depart/2/edit/
    path('depart//edit/', depart.depart_edit),

    path('user/list/', user.user_list),
    path('user/add/', user.user_add),
    path('user//edit/', user.user_edit),
    path('user//delete/', user.user_delete),

    path('pretty/list/', pretty.pretty_list),
    path('pretty/add/', pretty.pretty_add),
    path('pretty//edit/', pretty.pretty_edit),
    path('pretty//delete/', pretty.pretty_delete),

    path('admin/add/', admin.admin_add),
    path('admin/list/', admin.admin_list),
    path('admin//edit/',admin.admin_edit),

    path('login/account/',account.login),      #这个是登录的
]

在写登录的视图函数account.py
我把不同模块的视图函数拆分了,不同功能模块的一个py文件,在app01目录下创建目录views, 在views目录下分类写视图函数,主要要把原始的views.py文件删除
登录使用的Form组件
获取到用户输入的数据后要对数据进行校验,根数据库里面的值
再有如果验证通过要request.session 通过这个生成session, django会自动处理,生成一个session保存到数据库,并把这个session返回给浏览器。

from django.shortcuts import render,redirect
from django import forms
from app01.utils.encrypt import md5
from app01 import models


class LoginForm(forms.Form):
    username = forms.CharField(
        label="用户名",
        widget=forms.TextInput,
        required=True,
    )
    passwd = forms.CharField(
        label="密码",
        widget=forms.PasswordInput(render_value=True),
        required=True
    )
    # 这个init方式是给自己加样式的
    def __init__(self, *args,**kwargs):
        super().__init__(*args,**kwargs)

        for name ,field in self.fields.items():
            #字段中有属性,保留原来的属性,没有属性,才增加
            if field.widget.attrs:
                field.widget.attrs["class"] = "form-control"
                field.widget.attrs["placeholder"] = field.label
            else:
                field.widget.attrs = {"class":"form-control"}


def login(request):
    """用户登录"""
    if request.method == 'GET':
        form = LoginForm()
        return render(request,'login.html',{'form':form})

    form = LoginForm(data=request.POST)
    if form.is_valid():
        #print(form.cleaned_data)   #获取到的值是一个字典{'username': 'root', 'passwd': '1234'}
        #校验数据库的用户名和密码
        admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
        if not admin_object:
            form.add_error('passwd','用户名或密码错误')
            return render(request,'login.html',{'form':form})
        #用户名和密码正确
        #网站生成随机字符串; 写到用户浏览器的cookie中,再写入到session中
        request.session['info'] = {'id':admin_object.id,'name':admin_object.username}
        return redirect('/admin/list/')
    return render(request,'login.html',{'form':form})

login.html 的内容

{% load static %}
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
    <style>
        .account {
            width: 400px;
            border-radius: 5px;
            border: 1px solid #dddddd;
            box-shadow: 5px 5px 20px #aaa;

            margin-left: auto;
            margin-right: auto;
            margin-top: 100px;
            padding: 20px 40px;
        }
        .account h2 {
            margin-top: 10px;
            text-align: center;
        }
    style>
head>
<body>
<div class="account">
    <h2>用户登录h2>
      <form  method="post" novalidate>
          {% csrf_token %}
                    {% for field in form %}
                      <div class="form-group">
                        <label >{{ field.label }}label>
                        {{ field }}
                      <span style="color:red">{{ field.errors.0 }}span>
                      div>
          {% endfor %}
          <button type="submit" class="btn btn-primary">提交button>
      form>

div>

<script src="{% static 'js/jquery-3.7.0.min.js' %}">script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}">script>
body>
html>

3、中间件实现登录鉴权

在开始我们写了一个功能后,把django项目运行起来,直接方法url就能访问到了,正常来说是只有登录后的用户才能访问到,django中给我们提供了中间件,可以通过中间件来实现鉴权

django实现登录和登录的鉴权_第1张图片
在django 中可以定义多个中间件,中间件就是一个类,类里面定义有两个函数一个是process_request进入的,穿过所有的中间件到达视图函数,视图函数返回结果通过process_response函数返回给浏览器

  • 定义中间件
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect

class AuthMiddleWare(MiddlewareMixin):
    """中间件判断是否登录"""

    def process_request(self,request):
        # 1、排除那些不需要登录就能访问的页面
        # request.path_info  获取当前用户请求的URL  ru /login/account/
        if request.path_info == '/login/account/':
            return
        # 2、读取当前访问的用户的session信息,如果能读到,说明以登录过,就可以继续向后走
        info_dict = request.session.get("info")
        if info_dict:
            return
        # 3、没有登录过,重新回到登录页面
        return redirect('/login/account/')

  • 使用中间件,在settings.py中注册中间件
    会按这个顺序执行,中间件定义好后,会自动调佣
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'app01.middleware.auth.AuthMiddleWare',
]

中间件添加好后,你再没有登录的情况下去访问http://127.0.0.1:8000/user/list/ 这些页面会自动跳转到登录界面。

你可能感兴趣的:(python,django,sqlite,数据库)