首页 > 其他分享 > 00- 工具类

00- 工具类

时间:2023-02-01 11:59:32浏览次数:43  
标签:00 querty self request page dict 工具 class

一. 登陆前置

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

相关文章

  • 【FFH】 gn项目构建工具学习记录
    gn项目构建工具学习我们为何要使用构建工具?对于一个新手入门简单的helloworld程序而言,我们可以直接使用gcc命令对其进行编译。对于OpenHarmony系统而言,代码规模庞大,再想要......
  • Guava:google公司开发的一款Java类库扩展工具包
    Guava是google公司开发的一款Java类库扩展工具包文档https://github.com/google/guavahttps://github.com/google/guava/wikihttps://guava.dev/releases/snapshot-jre......
  • 跟着廖雪峰学 python 002
    ​ ​编辑 #表示注释:表示缩进的语句是代码块(缩进一般是四个空格)数据类型整数:        在程序中的表示方法和数学上的写法一模一样(正整数和负整数) ......
  • 爬虫工具(tkinter+scrapy+pyinstaller)
    需求介绍输入:关键字文件,每一行数据为一爬取单元。若一行存在多个and关系的关键字,则用|隔开处理:爬取访问6个网站的推送,获取推送内容的标题,发布时间,来源,正文第一段(不是图片......
  • wpa_supplicant - 强有力的终端 wifi 配置工具
    最近网购了一套Raspberry-Pi2,用来跑一些神秘脚本。因为树莓派是基于ARM架构的,所以给它装上了 Ubuntu专版,对于终端下基本的 iwconfig 命令可能对现代的多种加密方式的......
  • ASUS-H110M-K+i5-7400 电脑 Hackintosh 黑苹果efi引导文件
    原文来源于黑果魏叔官网,转载需注明出处。硬件型号驱动情况主板ASUS-H110M-K处理器Intel(R)Core(TM)[email protected]已驱动内存G-SkillDDR42400MHz8GB×2双通......
  • logging --- Python 的日志记录工具
    logging ---Python的日志记录工具源代码: Lib/logging/__init__.pyImportant此页面仅包含API参考信息。教程信息和更多高级用法的讨论,请参阅基础教程进阶教......
  • 弱网测试利器-Charles工具实战
    每天进步一点点,关注我们哦,每天分享测试技术文章本文章出自【码同学软件测试】码同学公众号:自动化软件测试,领取资料可加:magetest码同学抖音号:小码哥聊软件测试一:弱网测......
  • 字节二面:100Wqps短链系统,如何设计?
    文章很长,而且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面......
  • 国内网站 ICP 备案号查询工具 All In One
    国内网站ICP备案号查询工具AllInOneICP备案号查询公安机关互联网站安全管理服务平台https://www.beian.gov.cn/portal/registerSystemInfodemosheytapimage.......