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

  

原文地址:https://www.cnblogs.com/xiguatian/p/7028745.html