一. 登陆前置
1. 中间件
# 中间件介绍
# 1. 在中间件的process_request方法:
# 如果方法中没有返回值(返回None),继续向后走
# 如果方法中有返回值 HttpResponse render redirect,则不再继续向后执行
# 2. 想要应用中间件需要在setting.py中注册中间件. MIDDLEWARE=[]编写中间件路径
# 1. 在APP中-->新建文件midviews --> auth.py
# 2. 在 项目中的setting.py 中配置路径
'app01.midviews.auth.M1',
'app01.midviews.auth.M2',
谁在前面就先执行谁
# 中间件体验
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class M1(MiddlewareMixin):
"""中间件1"""
def process_request(self, request):
# 如果方法中没有返回值(返回None),继续向后走
# 如果方法中有返回值 HttpResponse render redirect
print("中间件请求")
return HttpResponse("无权访问")
def process_response(self, request, response):
print("中间件响应")
return response
class M2(MiddlewareMixin):
"""中间件2"""
def process_request(self, request):
print("M2.请求")
def process_response(self, request, response):
print("M2.响应")
return response
# 中间件执行登陆效验
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect
class AuthMiddleware(MiddlewareMixin):
def process_request(self, request):
# 0. 排除那些不需要登陆就能访问的页面
# request.path_info 获取当前用户请求的URL /login/
if request.path_info in ["/login/", "/image/code/"]:
return
# 1. 读取当前访问的用户的session信息,如果能读到,说明已登陆,就可以继续往后走
# 检查用户是否已登陆,已登陆可以继续向下走,未登录,跳转登陆页面
# 用户发来请求,获取cookie随机字符串,拿着随机字符串查看session中有没有
info_dict = request.session.get("info")
# print("info_dict=",info_dict)
if info_dict:
return
# 2. 没有登陆信息,重新回到登陆页面
return redirect("/login/")
2. 图片验证码
# 1. 下载第三方库
pip install pillow
# 2. 下载Monaco.ttf字体--> 放到根目录
https://www.du114.com/soft/409055.html
# 3. 初始 pillow
# 1. 创建一张图片,会保存在内存中
from PIL import Image, ImageDraw, ImageFont
# size: 大小 color:颜色
img = Image.new(mode="RGB", size=(120, 30), color=(255, 255, 255))
# 创建一个画笔
draw = ImageDraw.Draw(img, mode="RGB")
# 下载字体文件,引用
font = ImageFont.truetype("Monaco.ttf", 20)
# 写入文本(坐标,内容,颜色,字体(非必填))
draw.text([0, 0], "python", "red", font=font)
# 保存到本地
with open("code.png", "wb") as f:
img.save(f, format="png")
# 验证码封装
# 1.. 在APP里新建 utils文件--> code.py
import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter
# Monaco.ttf字体文件,需要在网上下载,如果提示错误,就改成: E:/Django_auto/mo.ttf
def check_code(width=120, height=30, char_length=5, font_file="Monaco.ttf", font_size=20):
code = []
# 创建一张图片
img = Image.new(mode="RGB", size=(width, height), color=(255, 255, 255))
# 创建一个画笔
draw = ImageDraw.Draw(img, mode="RGB")
def rndChar():
"""生成随机字母"""
# return chr(random.randint(65, 90))
"""随机数字"""
return str(random.randint(0, 9))
def rndColor():
"""随机生成颜色"""
return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
# 写文字
font = ImageFont.truetype(font_file, font_size)
for i in range(char_length):
char = rndChar()
code.append(char)
h = random.randint(0, 4)
draw.text([i * width / char_length, h], char, font=font, fill=rndColor())
# 写干扰点
for i in range(40):
draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
# 写干扰圆圈
for i in range(40):
draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
x = random.randint(0, width)
y = random.randint(0, height)
draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())
# 写干扰线
for i in range(5):
x1 = random.randint(0, width)
y1 = random.randint(0, height)
x2 = random.randint(0, width)
y2 = random.randint(0, height)
draw.line((x1, y1, x2, y2), fill=rndColor())
img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
return img, "".join(code)
3.md5加密
# APP-->utils-->md5_data.py
from bbc_auto import settings
# setting中有默认的随机生成的言
import hashlib
def md5(data_string):
# salt = "xxxxx" # 因为加密方式是固定的,所以加个言
# obj = hashlib.md5(salt.encode("utf-8"))
obj = hashlib.md5(settings.SECRET_KEY.encode("utf-8"))
obj.update(data_string.encode("utf-8"))
return obj.hexdigest()
二. ModelForm和Form
1. modelform 和 bootstrap
1. modelform可以帮助我们生成html标签
from django import forms
class UserModelForm(forms.ModelForm):
# 重新添加效验
name = forms.CharField(min_length=3, label="用户名")
class Meta:
model = models.User # 获取数据库User类的验证规则
fields = ["name", "password",] # 获取表头
form = UserModelForm()
{{ form.name }} 普通的input框
{{ form.password }} 普通的input框
2. 可以定义插件
# 第一种
class UserModelForm(forms.ModelForm):
class Meta:
model = models.User # 获取数据库User类的验证规则
fields = ["name", "password",] # 获取表头
widgets={
"name": forms.TextInput(attrs={"class":"form-control"}),
"password": forms.PasswordInput(attrs={"class":"form-control"})
}
# 第二种
class UserModelForm(forms.ModelForm):
name = forms.CharField(min_length=3,
label="用户名",
widgets={"name": forms.TextInput(attrs={"class":"form-control"}
)
class Meta:
model = models.User # 获取数据库User类的验证规则
fields = ["name", "password",] # 获取表头
{{ form.name }} BootStrap的input框
{{ form.password }} BootStrap的input框
3. 重新定义init方法,批量设置
class UserModelForm(forms.ModelForm):
class Meta:
model = models.User # 获取数据库User类的验证规则
fields = ["name", "password", "age", ] # 获取表头
def __init__(self, *args, **kwargs): # 重写父类方法
super().__init__(*args, **kwargs)
# 循环ModelForm中的所有字段,给每个字段的插件设置attrs
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",
"placeholder": field.label} # 获取数据库备注信息:field.label
2. 重复写,太麻烦,自定义公共父类
# 在APP-->utils-->bootstrap.py
from django import forms
class BootStrap:
bootstrap_exclude_fields = [] # 定义空列表
def __init__(self, *args, **kwargs): # 重写父类方法
super().__init__(*args, **kwargs)
# 循环ModelForm中的所有字段,给每个字段的插件设置attrs
for name, field in self.fields.items():
if name in self.bootstrap_exclude_fields:
continue # 如果列表中写了那个名字就移除样式(跳过)
# 如果字段中有属性,保留原来的属性,没有属性,才增加
if field.widget.attrs:
field.widget.attrs["class"] = "form-control"
field.widget.attrs["placeholder"] = field.label
else:
field.widget.attrs = {
"class": "form-control",
"placeholder": field.label} # 获取数据库备注信息:field.label
class BootStrapModelForm(BootStrap, forms.ModelForm):
pass
class BootStrapForm(BootStrap, forms.Form):
pass
三. 分页
# 自定义的分页组件,以后想要使用分页组件需要做如下几件事:
# 在试图函数中
def phone_list(request):
# 1. 根据自己的情况筛选数据
queryset = models.PrettyNum.objects.all()
# 2.实例化分页对象
page_object = Pagination(request, queryset)
context = {
"phone": page_object.page_queryset, # 分完页的数据
"page_string": page_object.html() # 页码
}
return render(request, "phone_list.html", context)
# 在html页面中:
<ul class="pagination">
{{ page_string }}
</ul>
# 封装: # APP-->utils-->pagemtion.py
class Pagination(object):
def __init__(self, request, queryset, page_size=10, page_pram="page", plus=5):
"""
reuqest: 请求的对象
queryset: 符合条件的数据(根据这个数据进行分页处理)
page_size:每页显示多少条数据
page_pram: 在url中传递的获取分页的参数,例如: /phone/list?page=12
plus: 显示当前页的,前后几页(页码)
"""
from django.http.request import QueryDict
import copy
# 在正常的请求/响应周期中访问时,request.POST和request.GET上的QueryDict将是不可变的.
# 要获得可变版本,您需要使用QueryDict.copy()或者._mutable = True
querty_dict = copy.deepcopy(request.GET)
querty_dict._mutable = True
self.querty_dict = querty_dict # 将获取到的get内容重新赋值
self.page_pram = page_pram # 在url中传递的获取分页的参数,例如: /phone/list?page=12
# 对当前页进行判断
page = request.GET.get(page_pram, "1") # 获取当前页
if page.isdecimal(): # 检查字符串是否只包含十进制字符/如果字符串中的所有字符都是十进制字符。返回true,有一个不是则返回False
page = int(page)
else:
page = 1
self.page = page # 获取当前页
self.page_size = page_size # 每页显示条数
# 每页显示10条的内容
self.start = (page - 1) * page_size # 起始值
self.end = page * page_size # 结束值
# 到前端访问展示的页面:self.page_queryset
self.page_queryset = queryset[self.start:self.end] # 将从数据库获取到的内容进行切片-分页
# 获取数据库的总条数
phone_count = queryset.count()
# 总页码: 总条数 / 每页显示条数 = 总页数 零 几条
phone_page_count, div = divmod(phone_count, page_size) # divmod(): 两数相除,得到元祖,两个值,一个商,一个余数
if div: # 如果有余数,则总页数+1
phone_page_count += 1
self.phone_page_count = phone_page_count
self.plus = plus # 前后显示几页
def html(self):
# 计算出,显示当前页的前后5页
if self.phone_page_count <= 2 * self.plus + 1: # 判断页码是否小于 前后页相加
# 数据库中的数据比较少,没有达到 前后页总和 ,那就起始页=1 ,结束页=总页
start_page = 1
end_page = self.phone_page_count
else:
# 数据库中的数据比较多 > 前后页总和页
# 当前页小于 前页5 时(小极值)
if self.page <= self.plus: # 判断起始页
start_page = 1
end_page = 2 * self.plus + 1
else: # 判断尾页
# 当前页大于后页5
# 当前页 + 后页5 > 总页码
if self.page + self.plus > self.phone_page_count:
start_page = self.phone_page_count - 2 * self.plus
end_page = self.phone_page_count
else: # 正常显示
start_page = self.page - self.plus
end_page = self.page + self.plus
# 页码
from django.utils.safestring import mark_safe # 导入,表示标签是安全的,才会在前端展示
page_str_list = []
self.querty_dict.setlist(self.page_pram, [1]) # 允许设置自己的路径参数 page,1
# print(request.GET.urlencode()) # 带着原来的参数加上自己的参数,拼接url
# 首页
page_str_list.append('<li><a href="?{}">首页</a></li>'.format(self.querty_dict.urlencode())) # page=1
# print("self.querty_dict.urlencode()=", self.querty_dict.urlencode())
# 判断page
# 上一页
if self.page > 1:
self.querty_dict.setlist(self.page_pram, [self.page - 1]) # 设置自己的路径参数
prev = '<li><a href="?{}">上一页</a></li>'.format(self.querty_dict.urlencode())
else:
self.querty_dict.setlist(self.page_pram, [1]) # 设置自己的路径参数 page=1
prev = '<li><a href="?page={}">上一页</a></li>'.format(self.querty_dict.urlencode())
page_str_list.append(prev)
# 页面
for i in range(start_page, end_page + 1): # 循环所有页
self.querty_dict.setlist(self.page_pram, [i]) # 设置自己的路径参数
if i == self.page: # 加个样式:class="active"
ele = '<li class="active"><a href="?{}">{}</a></li>'.format(self.querty_dict.urlencode(), i)
else:
ele = '<li><a href="?{}">{}</a></li>'.format(self.querty_dict.urlencode(), i)
page_str_list.append(ele)
# print("page_str_list=",page_str_list)
# 下一页
if self.page < self.phone_page_count:
self.querty_dict.setlist(self.page_pram, [self.page + 1]) # 设置自己的路径参数
prev = '<li><a href="?{}">下一页</a></li>'.format(self.querty_dict.urlencode())
else:
self.querty_dict.setlist(self.page_pram, [self.phone_page_count]) # 设置自己的路径参数
prev = '<li><a href="?{}">下一页</a></li>'.format(self.querty_dict.urlencode())
page_str_list.append(prev)
# 尾页
self.querty_dict.setlist(self.page_pram, [self.phone_page_count]) # 设置自己的路径参数
page_str_list.append('<li><a href="?{}">尾页</a></li>'.format(self.querty_dict.urlencode()))
# 前端跳转功能
search_string = """
<li>
<form style="float:left; margin-left:-1px;" method="get">
<input name=page
style="position:relative;float:left;display:inline-block;width:80px;border-radius:0"
type="text" class="form-control" placeholder="页码">
<button style="border-radius:0" class="btn btn-default type=submit">跳转</button>
</form>
</li>
"""
page_str_list.append(search_string)
# print("-----",page_str_list)
page_string = mark_safe("".join(page_str_list)) # 表示安全的
return page_string
标签:00,querty,self,request,page,dict,工具,class
From: https://www.cnblogs.com/kh-1314/p/17025602.html