Python 21 Django 实用小案例

Posted Dandy Zhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 21 Django 实用小案例相关的知识,希望对你有一定的参考价值。

实用案例

     验证码与验证

   KindEditor

     组合搜索的实现

   单例模式

     beautifulsoup4

     

验证码与验证

需要安装Pillow模块

pip stall pillow

1、首先需要借助pillow模块用来画一个验证码图形,这里单独封装了一个py文件,调用一个方法就好了

 1 #!/user/bin/env python
 2 # -*-coding: utf-8-*-
 3 import random
 4 from PIL import ImageDraw,ImageFont,Image,ImageFilter
 5 
 6 
 7 def random_check_code(width=120, height=30, char_length=5, font_file=\'wryh.ttf\', font_size=28):
 8     code = []
 9     img = Image.new(mode=\'RGB\', size=(width, height), color=(255, 255, 255))
10     draw = ImageDraw.Draw(img, mode=\'RGB\')
11 
12     def rndChar():
13         """
14         生成随机字母
15         :return:
16         """
17         return chr(random.randint(65, 90))
18 
19     def rndColor():
20         """
21         生成随机颜色
22         :return:
23         """
24         return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))
25 
26     # 写文字
27     font = ImageFont.truetype(font_file, font_size)
28     for i in range(char_length):
29         char = rndChar()
30         code.append(char)
31         h = random.randint(0, 4)
32         draw.text([i * width / char_length, h], char, font=font, fill=rndColor())
33 
34     # 写干扰点
35     for i in range(40):
36         draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
37 
38     # 写干扰圆圈
39     for i in range(40):
40         draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
41         x = random.randint(0, width)
42         y = random.randint(0, height)
43         draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())
44 
45     # 画干扰线
46     for i in range(5):
47         x1 = random.randint(0, width)
48         y1 = random.randint(0, height)
49         x2 = random.randint(0, width)
50         y2 = random.randint(0, height)
51         draw.line((x1, y1, x2, y2), fill=rndColor())
52 
53     img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) #加滤镜,可以增加颜色的不同
54     return img, \'\'.join(code)
生成随机验证码

函数的参数都已在调用的时候修改。

2、登陆界面设计

假设验证码跟登录页面在同一函数一起生成,那么每次刷新验证码都需要整个页面一起重新加载;显然,这是不合理的。所以可以确定验证码跟登录界面是2个视图函数控制的。

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body style="margin: 0 auto;">
 8     <div id="main">
 9         <form method="post" action="/login/">
10             {% csrf_token %}
11             <p><label>用户名:</label><input type="text" name="user" /></p>
12             <p><label>密码:</label><input type="password" name="pwd" /></p>
13             <p><label>验证码:</label><input type="text" name="checkcode" /><img src="/check_code.html" /></p>
14             <p><input type="submit" /></p>
15         </form>
16     </div>
17 </body>
18 </html>
login html
1 def login(request):
2     if request.method == \'GET\':
3         return  render(request, \'login.html\')
login 视图函数

3、验证码

将验证码图片对象返回到模板

1 def check_code(request):
2     stream = BytesIO()  # 申请一段内存
3     img, code = random_check_code()  # 获取随机码跟随机码图片对象
4     img.save(stream, \'PNG\')  # 将随机码对象保存到内存对象中
5     request.session[\'CheckCode\'] = code  # 将随机字符串保存到session
6     return HttpResponse(stream.getvalue())  # 返回内存中的随机码图片对象
View Code

4、如何刷新验证码呢

直接将原路由系统通过点击事件赋值给src,浏览器默认是不会进行刷新的;所以这里有一个小技巧,我们可以获取src的值,在末尾加上一个?,这样就可以实现点击刷新了。

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body style="margin: 0 auto;">
 8     <div id="main">
 9         <form method="post" action="/login/">
10             {% csrf_token %}
11             <p><label>用户名:</label><input type="text" name="user" /></p>
12             <p><label>密码:</label><input type="password" name="pwd" /></p>
13             <p><label>验证码:</label><input type="text" name="checkcode" /><img src="/check_code.html" onclick="ImgChange(this);"/></p>
14             <p><input type="submit" /></p>
15         </form>
16     </div>
17 </body>
18 <script>
19     function ImgChange(ths) {
20         ths.src = ths.src + \'?\'
21     }
22 </script>
23 </html>
修改过的login html

开启验证码验证功能

 1 def login(request):
 2     if request.method == \'GET\':
 3         return  render(request, \'login.html\')
 4     elif request.method == \'POST\':
 5         checkcode = request.POST.get(\'checkcode\')
 6         code_session = request.session[\'CheckCode\']
 7         print(checkcode)
 8         print(code_session)
 9         if checkcode.upper() == request.session[\'CheckCode\'].upper():
10             return HttpResponse(\'验证成功\')
11         else:
12             return render(request, \'login.html\')
修改后的login 视图函数

 

 

KindEditor

1、官网下载

http://kindeditor.net/demo.php

2、文件夹解压文件说明

├── asp                          asp示例
├── asp.net                    asp.net示例
├── attached                  空文件夹,放置关联文件attached
├── examples                 HTML示例
├── jsp                          java示例
├── kindeditor-all-min.js 全部JS(压缩)
├── kindeditor-all.js        全部JS(未压缩)
├── kindeditor-min.js      仅KindEditor JS(压缩)
├── kindeditor.js            仅KindEditor JS(未压缩)
├── lang                        支持语言
├── license.txt               License
├── php                        PHP示例
├── plugins                    KindEditor内部使用的插件
└── themes                   KindEditor主题

3、基本使用

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <div style="margin: 0 auto; width: 500px;height: 300px;">
 9         <textarea id="content"></textarea>
10     </div>
11 
12     <script src="/static/jquery-3.2.1.js"></script>
13     <script src="/static/kindeditor/kindeditor-all-min.js"></script>
14     <script>
15         $(function() {
16             KindEditor.create("#content", {
17                 width: \'400px\',
18                 height: \'200px\'
19 
20             })
21         })
22     </script>
23 </body>
24 </html>
View Code

4、详细参数

http://kindeditor.net/docs/option.html

5、上传文件示例

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <form action="/upload_kind/" method="post">
 9 
10         <div style="margin: 0 auto; width: 500px;height: 300px;">
11             <textarea id="content"></textarea>
12         </div>
13     </form>
14     <script src="/static/jquery-3.2.1.js"></script>
15     <script src="/static/kindeditor/kindeditor-all-min.js"></script>
16     <script>
17         $(function() {
18             KindEditor.create("#content", {
19                 width: \'400px\',
20                 height: \'200px\',
21                 extraFileUploadParams:{\'csrfmiddlewaretoken\':"{{ csrf_token }}"},
22                 uploadJson:\'/upload_img/\',
23                 fileManagerJson: \'/upload_file_manage/\',
24                 allowImageUpload: true,
25                 allowFileManager:true
26             })
27         })
28     </script>
29 </body>
30 </html>
html
 1 def upload_img(request):
 2     f = request.FILES.get(\'imgFile\')
 3     import os
 4     path = os.path.join("static/images", f.name)
 5     with open(path, \'wb\') as file_obj:
 6         for chunck in f.chunks():
 7             file_obj.write(chunck)
 8     import json
 9     dic = {
10         \'error\': 0,
11         \'url\': \'/\' + path,
12         \'message\': \'错误了...\'
13     }
14     return HttpResponse(json.dumps(dic))
15 
16 def upload_file_manage(request):
17     import os,time,json
18     dic = {}
19     root_path = \'C:/Users/Administrator/Desktop/DownTimeAnalysis/static/\'
20     static_root_path = \'/static/\'
21     request_path = request.GET.get(\'path\')
22     if request_path:
23         abs_current_dir_path = os.path.join(root_path, request_path)
24         move_up_dir_path = os.path.dirname(request_path.rstrip(\'/\'))
25         dic[\'moveup_dir_path\'] = move_up_dir_path + \'/\' if move_up_dir_path else move_up_dir_path
26 
27     else:
28         abs_current_dir_path = root_path
29         dic[\'moveup_dir_path\'] = \'\'
30 
31     dic[\'current_dir_path\'] = request_path
32     dic[\'current_url\'] = os.path.join(static_root_path, request_path)
33 
34     file_list = []
35     for item in os.listdir(abs_current_dir_path):
36         abs_item_path = os.path.join(abs_current_dir_path, item)
37         a, exts = os.path.splitext(item)
38         is_dir = os.path.isdir(abs_item_path)
39         if is_dir:
40             temp = {
41                 \'is_dir\': True,
42                 \'has_file\': True,
43                 \'filesize\': 0,
44                 \'dir_path\': \'\',
45                 \'is_photo\': False,
46                 \'filetype\': \'\',
47                 \'filename\': item,
48                 \'datetime\': time.strftime(\'%Y-%m-%d %H:%M:%S\', time.gmtime(os.path.getctime(abs_item_path)))
49             }
50         else:
51             temp = {
52                 \'is_dir\': False,
53                 \'has_file\': False,
54                 \'filesize\': os.stat(abs_item_path).st_size,
55                 \'dir_path\': \'\',
56                 \'is_photo\': True if exts.lower() in [\'.jpg\', \'.png\', \'.jpeg\'] else False,
57                 \'filetype\': exts.lower().strip(\'.\'),
58                 \'filename\': item,
59                 \'datetime\': time.strftime(\'%Y-%m-%d %H:%M:%S\', time.gmtime(os.path.getctime(abs_item_path)))
60             }
61 
62         file_list.append(temp)
63     dic[\'file_list\'] = file_list
64     return HttpResponse(json.dumps(dic))
View

路由系统

    url(r\'^kind/$\', views.kind),
    url(r\'^upload_img/\', views.upload_img),  # 前面有一个kind,视图函数可以获取参数dir来区分是文件还是其他。
    url(r\'^upload_file_manage/\', views.upload_file_manage),

 

 

6、XSS过滤特殊标签

处理依赖

pip3 install beautifulsoup4
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 from bs4 import BeautifulSoup
 4 
 5 
 6 class XSSFilter(object):
 7     __instance = None
 8 
 9     def __init__(self):
10         # XSS白名单
11         self.valid_tags = {
12             "font": [\'color\', \'size\', \'face\', \'style\'],
13             \'b\': [],
14             \'div\': [],
15             "span": [],
16             "table": [
17                 \'border\', \'cellspacing\', \'cellpadding\'
18             ],
19             \'th\': [
20                 \'colspan\', \'rowspan\'
21             ],
22             \'td\': [
23                 \'colspan\', \'rowspan\'
24             ],
25

以上是关于Python 21 Django 实用小案例的主要内容,如果未能解决你的问题,请参考以下文章

Python实用案例,python10行脚本打造实时截图识别OCR,轻松搞定“百度文库”

分享一个 Python + Django 实现的电商小项目

实用———springmvc接收参数校验

《Python绝技:运用Python成为顶级黑客》 Python实用小工具

五个实用的Python案例题,非常有用!

Django 基础教程