• Python 自定义的实用并且通用的功能模块


    自动生称有多级关系的 HTML 标签

      1 class Create_Multistage_Html(object):
      2     """
      3     用于创建多级 HTML 标签,比如: 多级评论,基于权限管理的多级菜单
      4     利用了递归函数功能。
      5 
      6     使用方法:
      7         需要导入一下:
      8         from create_multistage_html import Create_Multistage_Html
      9         obj =  Create_Multistage_Html(comment_list,'nid', 'content', 'reply_id')
     10         obj.help()
     11 
     12     data_list:  是一个结构化好的数据,或者是用 ORM 的 values 取到的QuerySet数据;
     13     格式如下:
     14         data_list = [
     15             {id: 1, 'content': "顶级菜单", 'reply_id': None},
     16             {id: 2, 'content': "二级菜单", 'reply_id': 1},
     17             {id: 3, 'content': "二级菜单", 'reply_id': 1},
     18             {id: 4, 'content': "三级菜单", 'reply_id': 3},
     19             {id: 5, 'content': "顶级菜单", 'reply_id': None},
     20             {id: 6, 'content': "三级菜单", 'reply_id': 2},
     21         ]
     22         QuerySet数据格式:
     23         data_list = <QuerySet[
     24             {id: 1, 'content': "顶级菜单", 'reply_id': None},
     25             {id: 2, 'content': "二级菜单", 'reply_id': 1},
     26             {id: 3, 'content': "二级菜单", 'reply_id': 1},
     27             {id: 4, 'content': "三级菜单", 'reply_id': 3},
     28             {id: 5, 'content': "顶级菜单", 'reply_id': None},
     29             {id: 6, 'content': "三级菜单", 'reply_id': 2},
     30          ]>
     31     """
     32     def __init__(self,data_list,id_key,content_key,parent_id_key):
     33         """
     34         :param data_list:     有级别关系的数据,数据对象
     35         :param id_key:        数据中每一条记录 ID 的 key(字段名),字符类型
     36         :param content_key:   数据中的需要展示的内容的 key(字段名),字符类型;比如:评论内容,菜单名称
     37         :param parent_id_key: 记录每条记录的上级 ID 的 key(字段名),字符类型
     38         """
     39         self.data_list       = list(data_list)
     40         self.id              = id_key
     41         self.content         = content_key
     42         self.parent_id       = parent_id_key
     43         self.data_dict       = {}
     44         self.structured_data = {}
     45 
     46 
     47     def create_structured_data(self):
     48 
     49         for row in self.data_list:
     50             row['child'] = []
     51             self.data_dict[row[self.id]] = row
     52 
     53         for row in self.data_list:
     54             if row[self.parent_id]:
     55                 key = row[self.parent_id]
     56                 self.data_dict[key]['child'].append(row)
     57 
     58         for k, v in self.data_dict.items():
     59             if v[self.parent_id] == None:
     60                 self.structured_data[k] = v
     61         return  self.structured_data
     62 
     63     def create_child_node(self,childs):
     64         self.childs = childs
     65         previous = """
     66             <div class="comment">
     67                 <div class="content">
     68         """
     69         for child in self.childs:
     70             template = '<div class="items">%s</div>'
     71             content  = child['content']
     72             str_tge  = template %content
     73             previous = previous + str_tge
     74             if child['child']:
     75                 self.child_tge = self.create_child_node(child['child'])
     76                 previous = previous + self.child_tge
     77 
     78         end = """
     79                 </div>
     80             </div>
     81         """
     82         return previous + end
     83 
     84     def create_multistage_html(self):
     85         """
     86         最终生成多级别 HTML 标签
     87         :return: css 样式 和 具有等级关系且包含内容的 HTML 标签
     88         """
     89         self.structured_data= self.create_structured_data()
     90 
     91         previous = """
     92             <div class="comment">
     93                 <div class="content">
     94         """
     95         for k,v in self.structured_data.items():
     96             template = '<div class="items">%s</div>'
     97             content = v['content']
     98             str_tge = template % content
     99             previous = previous + str_tge
    100             if v['child']:
    101                 child_tge = self.create_child_node(v['child'])
    102                 previous = previous + child_tge
    103 
    104         end = """
    105                 </div>
    106             </div>
    107         """
    108         css = """
    109             .comment > .content{
    110                 margin-left: 30px;
    111             }
    112         """
    113         return css,previous + end
    114     def help(self):
    115         help_str = """
    116         # 1. 定义函数
    117         def test(request):
    118             # 2. 获取数据
    119             comment_list = models.Comment.objects.values('nid', 'content', 'reply_id', )
    120             # 3. 实例化对象
    121             str_obj = Create_Multistage_Html(comment_list,'nid', 'content', 'reply_id')
    122             # 4. 使用方法,并得到两个返回值
    123             css,str = str_obj.create_multistage_html()
    124             # 5. 把得到的数据返回给前端
    125             return render(request,"test.html",{'css':css,'str':str})
    126         """
    127         print(help_str)
    View Code

    自定义分页

    """
    使用方式:
        # views.py 的视图函数内:
    try:
        current_page = request.GET.get('p')
    except Exception as e:
        print(e)
        current_page = 1
    
    all_count = models.Student.objects.all().count()
    
    page_info = PageInfo(current_page, 10, all_count, request.path_info)
    
    user_list = models.Student.objects.all()[page_info.start():page_info.end()]
    
    
    return render(request, 'users/user_info.html',
                  {"user_list": user_list,
                   "page_str": page_info.page_str()})
    
       # 前端页面,基于 Bootstrap
      <div class="row">
           <nav aria-label="Page navigation">
              <ul class="pagination">
                {{ page_str |safe }}
              </ul>
           </nav>
        </div>
    
    
    """
    
    
    class PageInfo(object):
        def __init__(self,current_page,per_page_num,all_count,base_url,page_range=11):
            """
            :param current_page:  当前页
            :param per_page_num:  每页显示数据条数
            :param all_count:  数据源总条数
            :param base_url:  页码标签的前缀
            :param page_range:  每页最多显示的页码的标签个数,就是每页显示的页码范围
            """
            try:
                current_page = int(current_page)
            except Exception as e:
                current_page = int(1)
            self.current_page = current_page
            self.per_page_num = per_page_num
            self.all_count = all_count
            a,b = divmod(all_count,per_page_num)
            if b != 0:
                self.all_page = a + 1
            else:
                self.all_page = a
            self.base_url = base_url
            self.page_range = page_range
    
        def start(self):
            return (self.current_page - 1) * self.per_page_num
    
        def end(self):
            return self.current_page * self.per_page_num
    
        def page_str(self):
            """
            在HTML页面中显示页码信息
            :return:
            """
            page_list = []
    
    
            if self.current_page <=1:
                prev = '<li><a href="#">上一页</a></li>'
            else:
                prev = '<li><a href="%s?p=%s">上一页</a></li>' %(self.base_url,self.current_page-1,)
            page_list.append(prev)
    
            # 只有 8页
            if self.all_page <= self.page_range:
                start = 1
                end = self.all_page + 1
            else:
                # 页数 18
                if self.current_page > int(self.page_range/2):
                    # 当前页: 6,7,8,,9,100
                    if (self.current_page + int(self.page_range/2)) > self.all_page:
                        start = self.all_page - self.page_range + 1
                        end = self.all_page + 1
                    else:
                        start = self.current_page - int(self.page_range/2)
                        end = self.current_page + int(self.page_range/2) + 1
                else:
                    # 当前页: 1,2,3,4,5,
                    start = 1
                    end = self.page_range + 1
            for i in range(start,end):
                if self.current_page == i:
                    temp = '<li class="active"><a href="%s?p=%s">%s</a></li>' %(self.base_url,i,i,)
                else:
                    temp = '<li><a href="%s?p=%s">%s</a></li>' % (self.base_url, i, i,)
                page_list.append(temp)
    
    
            if self.current_page >= self.all_page:
                nex = '<li><a href="#">下一页</a></li>'
            else:
                nex = '<li><a href="%s?p=%s">下一页</a></li>' % (self.base_url,self.current_page + 1,)
            page_list.append(nex)
    
    
    
            return "".join(page_list)
    自定义分页

      

    自定义验证码

      1 #!/usr/bin/env python
      2 #coding:utf-8
      3 
      4 import random
      5 from PIL import Image, ImageDraw, ImageFont, ImageFilter
      6 # pip3 install Pillow
      7 
      8 _letter_cases = "abcdefghjkmnpqrstuvwxy"  # 小写字母,去除可能干扰的i,l,o,z
      9 _upper_cases = _letter_cases.upper()  # 大写字母
     10 _numbers = ''.join(map(str, range(3, 10)))  # 数字
     11 init_chars = ''.join((_letter_cases, _upper_cases, _numbers))
     12 
     13 def create_validate_code(size=(120, 30),
     14                          chars=init_chars,
     15                          img_type="GIF",
     16                          mode="RGB",
     17                          bg_color=(255, 255, 255),
     18                          fg_color=(0, 0, 255),
     19                          font_size=18,
     20                          font_type="Monaco.ttf",
     21                          length=4,
     22                          draw_lines=True,
     23                          n_line=(1, 2),
     24                          draw_points=True,
     25                          point_chance = 2):
     26     '''
     27     @todo: 生成验证码图片
     28     @param size: 图片的大小,格式(宽,高),默认为(120, 30)
     29     @param chars: 允许的字符集合,格式字符串
     30     @param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
     31     @param mode: 图片模式,默认为RGB
     32     @param bg_color: 背景颜色,默认为白色
     33     @param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
     34     @param font_size: 验证码字体大小
     35     @param font_type: 验证码字体,默认为 ae_AlArabiya.ttf
     36     @param length: 验证码字符个数
     37     @param draw_lines: 是否划干扰线
     38     @param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效
     39     @param draw_points: 是否画干扰点
     40     @param point_chance: 干扰点出现的概率,大小范围[0, 100]
     41     @return: [0]: PIL Image实例
     42     @return: [1]: 验证码图片中的字符串
     43     '''
     44 
     45     width, height = size # 宽, 高
     46     img = Image.new(mode, size, bg_color) # 创建图形
     47     draw = ImageDraw.Draw(img) # 创建画笔
     48 
     49     def get_chars():
     50         '''生成给定长度的字符串,返回列表格式'''
     51         return random.sample(chars, length)
     52 
     53     def create_lines():
     54         '''绘制干扰线'''
     55         line_num = random.randint(*n_line) # 干扰线条数
     56 
     57         for i in range(line_num):
     58             # 起始点
     59             begin = (random.randint(0, size[0]), random.randint(0, size[1]))
     60             #结束点
     61             end = (random.randint(0, size[0]), random.randint(0, size[1]))
     62             draw.line([begin, end], fill=(0, 0, 0))
     63 
     64     def create_points():
     65         '''绘制干扰点'''
     66         chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100]
     67 
     68         for w in range(width):
     69             for h in range(height):
     70                 tmp = random.randint(0, 100)
     71                 if tmp > 100 - chance:
     72                     draw.point((w, h), fill=(0, 0, 0))
     73 
     74     def create_strs():
     75         '''绘制验证码字符'''
     76         c_chars = get_chars()
     77         strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开
     78 
     79         font = ImageFont.truetype(font_type, font_size)
     80         font_width, font_height = font.getsize(strs)
     81 
     82         draw.text(((width - font_width) / 3, (height - font_height) / 3),
     83                     strs, font=font, fill=fg_color)
     84 
     85         return ''.join(c_chars)
     86 
     87     if draw_lines:
     88         create_lines()
     89     if draw_points:
     90         create_points()
     91     strs = create_strs()
     92 
     93     # 图形扭曲参数
     94     params = [1 - float(random.randint(1, 2)) / 100,
     95               0,
     96               0,
     97               0,
     98               1 - float(random.randint(1, 10)) / 100,
     99               float(random.randint(1, 2)) / 500,
    100               0.001,
    101               float(random.randint(1, 2)) / 500
    102               ]
    103     img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲
    104 
    105     img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大)
    106 
    107     return img, strs
    View Code

    自定义后台返回给前台的 AJAX 的响应数据 

        class BaseReponse:
            def __init__(self):
                self.status = False
                self.data = None
                self.error = None
    

      

  • 相关阅读:
    零元尝鲜|阿里云 Grafana 商业化服务正式发布
    报名进入尾声,赶快申请加入 sealer 开源之夏吧!
    阿里巴巴在 Envoy Gateway 的演进历程浅析
    Nacos 开源之夏 2022 来了
    从“预见”到“遇见” | SAE 引领应用步入 Serverless 全托管新时代
    OpenClusterManagement 开源之夏 2022 来了
    阿里云“大算力”支持嬴彻自动驾驶仿真提速 20 倍
    开源夜聊栏目开播:聊聊新晋 CNCF 项目 sealer 背后的故事
    最佳实践|从Producer 到 Consumer,如何有效监控 Kafka
    阿里云性能测试 PTS 4 月新功能
  • 原文地址:https://www.cnblogs.com/xiguatian/p/7028745.html
Copyright © 2020-2023  润新知