通过django中间件和python魔法方法实现自定义session(通过文件存储session)
2021-04-27 07:28
阅读:546
YPE html>
标签:url you rem 技术 http local direct rip __init__
思路:
# 首先设置一个继承dict的类MysessionDict(用来设置session,例如request.mysession) # 请求来的时候 # 1、生成一个空的MysessionDict对象;request.mysession = MysessionDict() # 2、过滤url,如果请求是"/login/","/register/"就直接通过,不用获取cookie # 3、获取请求的cookie,如果有随机字符串,则拿着这个随机字符串到存放session的文件中去匹配是否存在这个cookie,如果存着取出对应的值并赋值给request.mysession.data # 请求走的时候 # 首先判断请求的url如果是"/login/"并且mysession操作方式是修改,如果是"/login/"(不是则不做处理): # 生成随机字符串, # 获取request.POST中的用户名和密码信息存放在data变量中 # 将随机字符串和data通过方法将信息存放到文件中 # 将随机字符串赋值给cookie,键为"mysession_id"; # response.set_cookie(‘mysession_id‘, random_str) # 如果是删除操作 # 删除文件中session,并删除cookie
代码:
设置字典的MysessionDict.py
class MysessionDict(dict): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.modified = False self.deleted = False @staticmethod def check_type_of_key(key): return isinstance(key, str) or False def __setattr__(self, key, value): if not self.check_type_of_key(key): raise TypeError( "The type of key must be ‘str‘ " ) if key not in [‘modified‘, ‘deleted‘]: self[‘modified‘] = True super().__setattr__(key, value) def __getattr__(self, item): return self.__dict__.get(item) def __setitem__(self, key, value): if not self.check_type_of_key(key): raise TypeError( "The type of key must be ‘str‘ " ) if key not in [‘modified‘, ‘deleted‘]: self.modified = True setattr(self, key, value) def __getitem__(self, item): return getattr(self, item, None) def flush(self): self.deleted = True
操作session文件的方法encrypt.py
import json import os # 保存session到文件中 def dump(data, random_str): with open("static/session.txt", "a") as f: json_data = json.dumps(data) all_data = "%s|%s" % (random_str, json_data) f.write("{}\n".format(all_data)) # 从文件中取出session_id对应的session值 def load(random_str): with open("static/session.txt", "r") as f: for line in f: if random_str in line: line = line.strip("\n") line_list = line.split("|")[1] data = json.loads(line_list) return data # 删除cookie def delete(random_str): with open("static/session.txt", "r") as f, open("static/session.txt.swap", "w", encoding="utf-8") as fw: for line in f: if random_str in line: line = "" fw.write("{}".format(line)) os.remove("static/session.txt") os.rename("static/session.txt.swap", "static/session.txt")
中间件mysession.py
from django.utils.deprecation import MiddlewareMixin from app01.mymiddleware.utils.MysessionDict import MysessionDict from app01.mymiddleware.utils.encrypt import dump, load, delete from django.shortcuts import redirect import uuid IgnoreUrl = [‘/login/‘, ‘/register/‘] class MyMiddleware(MiddlewareMixin): def process_request(self, request): request.mysession = MysessionDict() target_url = request.get_full_path() if target_url not in IgnoreUrl: random_str = request.COOKIES.get("mysession_id") if not random_str: return redirect("login") data = load(random_str) request.mysession.data = data def process_response(self, request, response): if request.mysession.modified and request.get_full_path() == "/login/": random_str = str(uuid.uuid1()) data = { "username": request.POST.get(‘username‘), "password": request.POST.get(‘password‘) } dump(data,random_str) response.set_cookie(‘mysession_id‘, random_str) request.mysession["modified"] = False if request.mysession.deleted: random_str = request.COOKIES.get("mysession_id") delete(random_str) response.delete_cookie("mysession_id") return response
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r‘^admin/‘, admin.site.urls), # 注册 url(r‘^register/‘, views.register), # 登录 url(r‘^login/‘, views.login,name="login"), url(r‘^logout/‘, views.logout), url(r‘^index/‘, views.index), ]
views.py
from django.shortcuts import render, HttpResponse, redirect from django.http import JsonResponse from app01.register_forms import RegisterForms from app01 import models import json # Create your views here. def register(request): form_obj = RegisterForms() if request.method == "POST": back_code = {"code": 200, "msg": ""} data = json.loads(request.body) form_obj = RegisterForms(data) if form_obj.is_valid(): clean_data = form_obj.cleaned_data clean_data.pop("re_password") models.Userinfo.objects.create(**clean_data) back_code["msg"] = "注册成功" back_code["url"] = "/login/" else: back_code["code"] = 300 back_code["msg"] = form_obj.errors return JsonResponse(back_code) return render(request, "register.html", locals()) def login(request): if request.method == "POST": username = request.POST.get("username") password = request.POST.get("password") user_obj = models.Userinfo.objects.filter(username=username,password=password).first() if user_obj: request.mysession["modified"] = True return HttpResponse("ok") return render(request, "login.html") def logout(request): request.mysession.flush() return redirect("login") def index(request): print(request.mysession.data) if request.mysession.data: return JsonResponse(request.mysession.data) return HttpResponse("index")
models.py
from django.db import models # Create your models here. class Userinfo(models.Model): username = models.CharField(max_length=16, verbose_name="用户名") password = models.CharField(max_length=16, verbose_name="密码") age = models.IntegerField(verbose_name="年龄")
register_forms.py
from django import forms from app01 import models class RegisterForms(forms.Form): username = forms.CharField(max_length=16, min_length=4, label="用户名", error_messages={ ‘min_length‘: ‘用户名最少4位‘, ‘max_length‘: ‘用户名最大16位‘, ‘required‘: "用户名不能为空" }, widget=forms.widgets.TextInput(attrs={‘class‘: ‘form-control‘}) ) password = forms.CharField(max_length=16, min_length=4, label="密码", error_messages={ ‘min_length‘: ‘密码最少4位‘, ‘max_length‘: ‘密码最大16位‘, ‘required‘: "密码不能为空" }, widget=forms.widgets.PasswordInput(attrs={‘class‘: ‘form-control‘}) ) re_password = forms.CharField(max_length=16, min_length=4, label="确认密码", error_messages={ ‘min_length‘: ‘确认密码最少4位‘, ‘max_length‘: ‘确认密码最大16位‘, ‘required‘: "确认密码不能为空" }, widget=forms.widgets.PasswordInput(attrs={‘class‘: ‘form-control‘}) ) age = forms.CharField(label="年龄", error_messages={ ‘required‘: "年龄不能为空" }, widget=forms.widgets.TextInput(attrs={‘class‘: ‘form-control‘}) ) def clean_username(self): username = self.cleaned_data.get("username") user_obj = models.Userinfo.objects.filter(username=username).first() if user_obj: self.add_error("username", "用户已存在") if username.endswith("sb"): self.add_error("username", "用户名不能以sb结尾") return username def clean_age(self): age = self.cleaned_data.get("age") age = int(age) if not (age and age >18): self.add_error("age", "年龄必须小于150,大于18") age = str(age) return age def clean(self): password = self.cleaned_data.get("password") re_password = self.cleaned_data.get("re_password") if not password == re_password: self.add_error("re_password", "两次密码不一致") return self.cleaned_data
login.html
"en">"UTF-8">Title "https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> "https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> {% load static %}class="container-fluid">class="row">class="col-md-8 col-md-offset-2">class="text-center">登录界面
register.html
"en"> "UTF-8">Title "https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> "https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> {% load static %}class="container-fluid">class="row">class="col-md-8 col-md-offset-2">class="text-center">注册页面
通过django中间件和python魔法方法实现自定义session(通过文件存储session)
标签:url you rem 技术 http local direct rip __init__
原文地址:https://www.cnblogs.com/baicai37/p/13245707.html
文章来自:搜素材网的编程语言模块,转载请注明文章出处。
文章标题:通过django中间件和python魔法方法实现自定义session(通过文件存储session)
文章链接:http://soscw.com/index.php/essay/79999.html
文章标题:通过django中间件和python魔法方法实现自定义session(通过文件存储session)
文章链接:http://soscw.com/index.php/essay/79999.html
评论
亲,登录后才可以留言!