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

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

class Create_Multistage_Html(object):
    """
    用于创建多级 HTML 标签,比如: 多级评论,基于权限管理的多级菜单
    利用了递归函数功能。

    使用方法:
        需要导入一下:
        from create_multistage_html import Create_Multistage_Html
        obj =  Create_Multistage_Html(comment_list,'nid', 'content', 'reply_id')
        obj.help()

    data_list:  是一个结构化好的数据,或者是用 ORM 的 values 取到的QuerySet数据;
    格式如下:
        data_list = [
            {id: 1, 'content': "顶级菜单", 'reply_id': None},
            {id: 2, 'content': "二级菜单", 'reply_id': 1},
            {id: 3, 'content': "二级菜单", 'reply_id': 1},
            {id: 4, 'content': "三级菜单", 'reply_id': 3},
            {id: 5, 'content': "顶级菜单", 'reply_id': None},
            {id: 6, 'content': "三级菜单", 'reply_id': 2},
        ]
        QuerySet数据格式:
        data_list = <QuerySet[
            {id: 1, 'content': "顶级菜单", 'reply_id': None},
            {id: 2, 'content': "二级菜单", 'reply_id': 1},
            {id: 3, 'content': "二级菜单", 'reply_id': 1},
            {id: 4, 'content': "三级菜单", 'reply_id': 3},
            {id: 5, 'content': "顶级菜单", 'reply_id': None},
            {id: 6, 'content': "三级菜单", 'reply_id': 2},
         ]>
    """
    def __init__(self,data_list,id_key,content_key,parent_id_key):
        """
        :param data_list:     有级别关系的数据,数据对象
        :param id_key:        数据中每一条记录 ID 的 key(字段名),字符类型
        :param content_key:   数据中的需要展示的内容的 key(字段名),字符类型;比如:评论内容,菜单名称
        :param parent_id_key: 记录每条记录的上级 ID 的 key(字段名),字符类型
        """
        self.data_list       = list(data_list)
        self.id              = id_key
        self.content         = content_key
        self.parent_id       = parent_id_key
        self.data_dict       = {}
        self.structured_data = {}


    def create_structured_data(self):

        for row in self.data_list:
            row['child'] = []
            self.data_dict[row[self.id]] = row

        for row in self.data_list:
            if row[self.parent_id]:
                key = row[self.parent_id]
                self.data_dict[key]['child'].append(row)

        for k, v in self.data_dict.items():
            if v[self.parent_id] == None:
                self.structured_data[k] = v
        return  self.structured_data

    def create_child_node(self,childs):
        self.childs = childs
        previous = """
            <div class="comment">
                <div class="content">
        """
        for child in self.childs:
            template = '<div class="items">%s</div>'
            content  = child['content']
            str_tge  = template %content
            previous = previous + str_tge
            if child['child']:
                self.child_tge = self.create_child_node(child['child'])
                previous = previous + self.child_tge

        end = """
                </div>
            </div>
        """
        return previous + end

    def create_multistage_html(self):
        """
        最终生成多级别 HTML 标签
        :return: css 样式 和 具有等级关系且包含内容的 HTML 标签
        """
        self.structured_data= self.create_structured_data()

        previous = """
            <div class="comment">
                <div class="content">
        """
        for k,v in self.structured_data.items():
            template = '<div class="items">%s</div>'
            content = v['content']
            str_tge = template % content
            previous = previous + str_tge
            if v['child']:
                child_tge = self.create_child_node(v['child'])
                previous = previous + child_tge

        end = """
                </div>
            </div>
        """
        css = """
            .comment > .content{
                margin-left: 30px;
            }
        """
        return css,previous + end
    def help(self):
        help_str = """
        # 1. 定义函数
        def test(request):
            # 2. 获取数据
            comment_list = models.Comment.objects.values('nid', 'content', 'reply_id', )
            # 3. 实例化对象
            str_obj = Create_Multistage_Html(comment_list,'nid', 'content', 'reply_id')
            # 4. 使用方法,并得到两个返回值
            css,str = str_obj.create_multistage_html()
            # 5. 把得到的数据返回给前端
            return render(request,"test.html",{'css':css,'str':str})
        """
        print(help_str)

2.自定义分页

"""
使用方式:
    # 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)

3.自定义验证码

import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter
# pip3 install Pillow
# Python学习交流群:711312441
_letter_cases = "abcdefghjkmnpqrstuvwxy"  # 小写字母,去除可能干扰的i,l,o,z
_upper_cases = _letter_cases.upper()  # 大写字母
_numbers = ''.join(map(str, range(3, 10)))  # 数字
init_chars = ''.join((_letter_cases, _upper_cases, _numbers))

def create_validate_code(size=(120, 30),
                         chars=init_chars,
                         img_type="GIF",
                         mode="RGB",
                         bg_color=(255, 255, 255),
                         fg_color=(0, 0, 255),
                         font_size=18,
                         font_type="Monaco.ttf",
                         length=4,
                         draw_lines=True,
                         n_line=(1, 2),
                         draw_points=True,
                         point_chance = 2):
    '''
    @todo: 生成验证码图片
    @param size: 图片的大小,格式(宽,高),默认为(120, 30)
    @param chars: 允许的字符集合,格式字符串
    @param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
    @param mode: 图片模式,默认为RGB
    @param bg_color: 背景颜色,默认为白色
    @param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
    @param font_size: 验证码字体大小
    @param font_type: 验证码字体,默认为 ae_AlArabiya.ttf
    @param length: 验证码字符个数
    @param draw_lines: 是否划干扰线
    @param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效
    @param draw_points: 是否画干扰点
    @param point_chance: 干扰点出现的概率,大小范围[0, 100]
    @return: [0]: PIL Image实例
    @return: [1]: 验证码图片中的字符串
    '''

    width, height = size # 宽, 高
    img = Image.new(mode, size, bg_color) # 创建图形
    draw = ImageDraw.Draw(img) # 创建画笔

    def get_chars():
        '''生成给定长度的字符串,返回列表格式'''
        return random.sample(chars, length)

    def create_lines():
        '''绘制干扰线'''
        line_num = random.randint(*n_line) # 干扰线条数

        for i in range(line_num):
            # 起始点
            begin = (random.randint(0, size[0]), random.randint(0, size[1]))
            #结束点
            end = (random.randint(0, size[0]), random.randint(0, size[1]))
            draw.line([begin, end], fill=(0, 0, 0))

    def create_points():
        '''绘制干扰点'''
        chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100]

        for w in range(width):
            for h in range(height):
                tmp = random.randint(0, 100)
                if tmp > 100 - chance:
                    draw.point((w, h), fill=(0, 0, 0))

    def create_strs():
        '''绘制验证码字符'''
        c_chars = get_chars()
        strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开

        font = ImageFont.truetype(font_type, font_size)
        font_width, font_height = font.getsize(strs)

        draw.text(((width - font_width) / 3, (height - font_height) / 3),
                    strs, font=font, fill=fg_color)

        return ''.join(c_chars)

    if draw_lines:
        create_lines()
    if draw_points:
        create_points()
    strs = create_strs()

    # 图形扭曲参数
    params = [1 - float(random.randint(1, 2)) / 100,
              0,
              0,
              0,
              1 - float(random.randint(1, 10)) / 100,
              float(random.randint(1, 2)) / 500,
              0.001,
              float(random.randint(1, 2)) / 500
              ]
    img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲

    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大)

    return img, strs

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

class BaseReponse:
    def __init__(self):
        self.status = False
        self.data = None
        self.error = None
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值