码迷,mamicode.com
首页 > 编程语言 > 详细

西游之路——python全栈——通用模块(pager、check_code、form验证)

时间:2018-10-02 22:25:58      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:turn   标签   numbers   regex   信息   更新   creat   NPU   name   

1、验证码

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

需要配合 MONACO.TTF 字体使用

2、分页

技术分享图片
 1 class Pagination(object):
 2     def __init__(self,totalCount,currentPage,CurentUrl,perPageItemNum=3,maxPageNum=3,):
 3         # 所有数据总个数
 4         self.total_count = int(totalCount)
 5         # 当前页
 6         try:
 7             v = int(currentPage)
 8             if v <= 0:
 9                 v = 1
10             self.current_page = v
11 
12         except Exception as e:
13             self.current_page = 1
14         # 每页显示行数
15         self.per_page_item_num = int(perPageItemNum)
16         # 最多页面数
17         self.max_page_num = int(maxPageNum)
18         self.current_url = CurentUrl
19 
20     def start(self):
21         return (self.current_page - 1)*self.per_page_item_num
22 
23     def end(self):
24         return self.current_page*self.per_page_item_num
25 
26     @property
27     def num_pages(self):
28         a,b = divmod(self.total_count,self.per_page_item_num)
29         if b == 0:
30             return a
31         return a+1
32 
33     @property
34     def pager_num_range(self):
35         # 当前页
36         # self.current_page
37         # 最多显示页码数 7
38         # self.per_page_num
39         # 总页数
40         # self.num_pages
41         # 判断最小极值
42         if self.max_page_num > self.num_pages:
43             # 根据当前页动态生成,设置页面显示数
44             return range(1, self.num_pages + 1)
45         # 总页数特别多时
46         part = int(self.max_page_num/2)
47 
48         if part >= self.current_page:
49             return range(1, self.max_page_num + 1)
50 
51         # 判断最大极值
52         if (self.current_page + part) >= self.num_pages:
53             return range(self.num_pages - self.max_page_num + 1, self.num_pages + 1)
54 
55         return range(self.current_page - part, self.current_page + part +1)
56 
57     def page_str(self):
58         page_list = []
59 
60         if self.current_page ==1:
61             prev = "<li><a href=‘#‘>上一页</a></li>"
62         else:
63             prev = "<li><a href=‘%s?p=%s‘>上一页</a></li>" %(self.current_url,self.current_page-1)
64         page_list.append(prev)
65 
66         first = "<li><a href=‘%s?p=1‘>首页</a></li>" % self.current_url
67         page_list.append(first)
68 
69         for i in self.pager_num_range:
70             if self.current_page == i:
71                 tem = "<li class=‘active‘><a href=‘%s?p=%s‘>%s</a></li>" % (self.current_url, i,i)
72             else:
73                 tem = "<li><a href=‘%s?p=%s‘>%s</a></li>" % (self.current_url, i, i)
74             page_list.append(tem)
75 
76         last = "<li><a href=‘%s?p=%s‘>尾页</a></li>" % (self.current_url, self.num_pages)
77         page_list.append(last)
78 
79         if self.current_page == self.num_pages:
80             nex = "<li><a href=‘#‘>下一页</a>"
81         else:
82             nex = "<li><a href=‘%s?p=%s‘>下一页</a></li>" % (self.current_url, self.current_page + 1)
83         page_list.append(nex)
84 
85         return ‘‘.join(page_list)
pager.py

使用时需要传入三个参数

  - 信息总数

  - 当前页

  - 当前url

技术分享图片
1 obj_list = Pagination(article_list.count(), current_page, current_url)
2     data_list = article_list[obj_list.start():obj_list.end()]
视图函数中代码

3、form验证

技术分享图片
  1 from django import forms
  2 from django.forms import fields,widgets
  3 from repository import models
  4 from django.core.exceptions import ValidationError
  5 
  6 class RegisterForm(forms.Form):
  7     username = fields.CharField(
  8         label=用户名,
  9         required=True,
 10         max_length=32,
 11         initial=请输入用户名,
 12         error_messages={
 13             required: 用户名不能为空,
 14             min_length: 用户名过短,
 15             invalid: 格式错误,
 16         }
 17     )
 18     password = fields.CharField(
 19         label=密码,
 20         required=True,
 21         max_length=32,
 22         min_length=6,
 23         error_messages={
 24             required: 密码不能为空,
 25             min_length: 密码长度太短,
 26             invalid: 格式有误,
 27         }
 28     )
 29     # fields.RegexField()   自定义正则
 30     confirm_pwd = fields.CharField(
 31         label=确认密码,
 32         required=True,
 33         max_length=32,
 34         min_length=6,
 35         error_messages={
 36             required: 密码不能为空,
 37             min_length: 密码长度太短,
 38             invalid: 格式有误,
 39         }
 40     )
 41     email = fields.EmailField(
 42         widget=widgets.EmailInput(attrs={"class":"form-control","placeholder": "输入邮箱"}),
 43         label=邮箱,
 44         required=True,
 45         error_messages={
 46             required: 不能为空,
 47         }
 48     )
 49     # 注意使用cleaned_data.get(‘username‘)取值
 50     def clean_username(self):
 51         ret = models.User.objects.filter(username=self.cleaned_data.get(username))
 52         if not ret:
 53             return self.cleaned_data.get(username)
 54         else:
 55             raise ValidationError(用户名已存在)
 56 
 57     def clean_password(self):
 58         pwd = self.cleaned_data.get(password)
 59         if not pwd.isdigit():
 60             return self.cleaned_data.get(password)
 61         else:
 62             raise ValidationError(不能全是数字)
 63 
 64     # 验证前后密码是否一致
 65     def clean(self):
 66         password = self.cleaned_data.get(password)
 67         confirm_pwd = self.cleaned_data.get(confirm_pwd)
 68         if confirm_pwd == password:
 69             return self.cleaned_data
 70         else:
 71             raise ValidationError(密码输入不一致)
 72 
 73 class LoginForm(forms.Form):
 74     username = fields.CharField(
 75         label=用户名,
 76         required=True,
 77         max_length=32,
 78         initial=请输入用户名,
 79         error_messages={
 80             required: 用户名不能为空,
 81         }
 82     )
 83     password = fields.CharField(
 84         label=密码,
 85         required=True,
 86         max_length=32,
 87         min_length=6,
 88         error_messages={
 89             required: 密码不能为空,
 90         }
 91     )
 92     def clean(self):
 93         user_list = models.User.objects.all().values_list(username,password)
 94         user_list = list(user_list)
 95         login_list = (self.cleaned_data.get(username),self.cleaned_data.get(password))
 96         if login_list in user_list:
 97             return self.cleaned_data
 98         else:
 99             raise ValidationError(用户名或密码错误)
100 
101 class ArticleForm(forms.Form):
102     title = fields.CharField(
103         label=标题,
104         widget=widgets.TextInput(attrs={class:form-control, placeholder:标题5-32个字符}),
105         required=True,
106         min_length=5,
107         max_length=32,
108         error_messages={
109             required:不能为空,
110             min_length:标题最少为5个字节,
111             max_length:标题最少为32个字节,
112         }
113     )
114     summary = fields.CharField(
115         label=简介,
116         required=True,
117         widget=widgets.Textarea(attrs={class:form-control, placeholder:简介10-64个字符}),
118         max_length=32,
119         min_length=10,
120         error_messages={
121             required:不能为空,
122             min_length:简介最少为10个字节,
123             max_length:简介最多为64个字节,
124         }
125     )
126     detail = fields.CharField(
127         label=内容,
128         required=True,
129         widget=widgets.Textarea(attrs={id:detail,class: kind-content, placeholder: 简介32-256个字符}),
130         max_length=256,
131         min_length=32,
132         error_messages={
133             required: 不能为空,
134             min_length: 简介最少为32个字节,
135             max_length: 简介最少为256个字节,
136         }
137     )
138     user_choice = models.User.objects.all().values_list(id,username)
139     user = fields.IntegerField(
140         label=作者,
141         widget=widgets.Select(choices=user_choice, attrs={class:form-control})
142     )
143     blog_choice = models.Blog.objects.all().values_list(id,title)
144     blog = fields.IntegerField(
145         label=博客,
146         widget=widgets.Select(choices=blog_choice, attrs={class:form-control})
147     )
148     tags_choice = models.Tags.objects.all().values_list(id, caption)
149     tags = fields.IntegerField(
150         label=标签,
151         widget=widgets.Select(choices=tags_choice, attrs={class:form-control})
152     )
153     category_choice = models.Category.objects.all().values_list(id,caption)
154     category = fields.IntegerField(
155         label=分类,
156         widget=widgets.Select(choices=category_choice, attrs={class:form-control})
157     )
158 
159     def clean(self):
160         self.cleaned_data[user_id] = self.cleaned_data.get(user)
161         self.cleaned_data[tags_id] = self.cleaned_data.get(tags)
162         self.cleaned_data[blog_id] = self.cleaned_data.get(blog)
163         self.cleaned_data[category_id] = self.cleaned_data.get(category)
164         del self.cleaned_data[user]
165         del self.cleaned_data[tags]
166         del self.cleaned_data[blog]
167         del self.cleaned_data[category]
168         return self.cleaned_data
169 
170 class TroubleForm(forms.Form):
171     title = fields.CharField(
172         label=标题,
173         required=True,
174         widget=widgets.TextInput(attrs={class:form-control, placeholder:输入标题5-32个字符}),
175         max_length=32,
176         min_length=5,
177         error_messages={
178             required:标题不能为空,
179             min_length:标题最少为5个字节,
180             invalid:格式错误,
181         }
182     )
183     detail = fields.CharField(
184         label=内容,
185         required=True,
186         widget=widgets.Textarea(attrs={id:detail,class:kind-content, placeholder:输入内容5-256个字符}),
187         max_length=256,
188         min_length=5,
189         error_messages={
190             required: 内容不能为空,
191             min_length: 内容最少为5个字节,
192             invalid: 格式错误,
193         }
194     )
注册、登录、编辑、添加

有关form组件详情:稍后更新

 

西游之路——python全栈——通用模块(pager、check_code、form验证)

标签:turn   标签   numbers   regex   信息   更新   creat   NPU   name   

原文地址:https://www.cnblogs.com/Lujun1028/p/9737857.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!