zoukankan      html  css  js  c++  java
  • tornado项目注意点

    大体框架思想

    如果你做的项目是偏向中小型的话,MTV或者MVC已经足够支撑起整个项目,而如果你做的项目比较大大话,或者说可能以后的业务量很大的话,那你就需要用到四层架构的思想了,那么我们就各自分析下俩框架的结构。

    1、MVC

     MVC是众所周知的模式,即:将应用程序分解成三个组成部分:model(模型),view(视图),和 controller(控制 器)。其中:
                 M 管理应用程序的状态(通常存储到数据库中),并约束改变状态的行为(或者叫做“业务规则”)。
                 C 接受外部用户的操作,根据操作访问模型获取数据,并调用“视图”显示这些数据。控制器是将“模型”和“视图”隔离,并成为二者之间的联系纽带。
                 V 负责把数据格式化后呈现给用户。

    2、四层框架

    我们通常所说的四层框架,实际上是DAO层、Service层、Controller层、View层这四层的相互组合形成。

    DAO层:DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口

    Service层:Service层主要负责业务模块的逻辑应用设计。同样是首先设计接口,再设计其实现的类

    Controller层:Controller层负责具体的业务模块流程的控制,在此层里面要调用Serice层的接口来控制业务流程

    View层 : 此层与控制层结合比较紧密,需要二者结合起来协同工发。View层主要负责前台jsp页面的表示

    UI--->Service---->Model------>Repository

    验证码

    验证码原理在于后台自动创建一张带有随机内容的图片,然后将内容通过img标签输出到页面

    安装图像处理模块:

    pip3 install pillow   
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import tornado.ioloop
    import tornado.web
    import io
    import check_code
    li = []
    class CheckCodeHandler(tornado.web.RequestHandler):
        def get(self):
            mstream = io.BytesIO()
            img, code = check_code.create_validate_code()
            li.append(code)   #这里可以保存到session中
            img.save(mstream, "GIF")
            self.write(mstream.getvalue())
            print(code)
    
    class LoginHandler(tornado.web.RequestHandler):
        def get(self):
            self.render('login.html',status="")
        def post(self, *args, **kwargs):
            user = self.get_argument("user",None)
            pwd = self.get_argument("pwd",None)
            mima = self.get_argument("mima",None)
            if user == "alex" and pwd == "123" and mima.upper() == li[0].upper():  #不区分大小写
                self.write("登录成功")
            else:
                # self.redirect("/login")
                self.render("login.html",status = "验证码错误")
    
    settings = {
        'template_path': 'tpl',
        'static_path': 'static',
        'static_url_prefix': '/static/',
        'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
    }
    
    application = tornado.web.Application([
        (r"/login", LoginHandler),
        (r"/check_code", CheckCodeHandler),
    ], **settings)
    
    
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    start.py
    #!/usr/bin/env python
    #coding:utf-8
    import random
    from PIL import Image, ImageDraw, ImageFont, ImageFilter
    
    _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
    check_code.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="/login" method="post">
        <p><input name="user" placeholder="用户名" type="text"></p>
        <p><input name="pwd" placeholder="密码" type="text"></p>
        <p>
          <input name="mima" placeholder="验证码" type="text" >
            <img src="/check_code" onclick='ChangeCode();' id='imgCode'>
        </p>
        <input type="submit" value="提交"><span style="color: red">{{status}}</span>
    </form>
    <script>
        function ChangeCode() {
            var code = document.getElementById('imgCode');
            code.src += '?';
        }
    </script>
    </body>
    </html>
    html

    Session全套

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from hashlib import sha1
    import os
    import time
    
    create_session_id = lambda: sha1(bytes('%s%s' % (os.urandom(16), time.time()), encoding='utf-8')).hexdigest()
    
    
    class SessionFactory:
    
        @staticmethod
        def get_session_obj(handler):
            obj = CacheSession(handler)
            return obj
    
    class CacheSession:
        session_container = {}
        session_id = "__sessionId__"
    
        def __init__(self, handler):
            self.handler = handler
            client_random_str = handler.get_cookie(CacheSession.session_id, None)
            if client_random_str and client_random_str in CacheSession.session_container:
                self.random_str = client_random_str
            else:
                self.random_str = create_session_id()
                CacheSession.session_container[self.random_str] = {}
    
            expires_time = time.time() + 60 * 20
            handler.set_cookie(CacheSession.session_id, self.random_str, expires=expires_time)
    
        def __getitem__(self, key):
            ret = CacheSession.session_container[self.random_str].get(key, None)
            return ret
    
        def __setitem__(self, key, value):
            CacheSession.session_container[self.random_str][key] = value
    
        def __delitem__(self, key):
            if key in CacheSession.session_container[self.random_str]:
                del CacheSession.session_container[self.random_str][key]
    Session.py
    所有类的继承BaseRequestHandler,继承后就可以用Session
    
    class BaseRequestHandler(tornado.web.RequestHandler):
        def initialize(self):
            self.session = SessionFactory.get_session_obj(self)

    通过self.session['xxx'] = xxx可以储存值

    通过self.session['xxx']可以取值

    Form验证

    1、验证规则文件

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import re
    import os
    
    class Field:
    
        def __init__(self):
    
            self.is_valid = False
            self.name = None
            self.value = None
            self.error = None
    
        def match(self, name, value):
            self.name = name
    
            if not self.required:
                self.is_valid = True
                self.value = value
            else:
                if not value:
                    if self.custom_error_dict.get('required', None):
                        self.error = self.custom_error_dict['required']
                    else:
                        self.error = "%s is required" % name
                else:
                    ret = re.match(self.REGULAR, value)
                    if ret:
                        self.is_valid = True
                        self.value = value
                    else:
                        if self.custom_error_dict.get('valid', None):
                            self.error = self.custom_error_dict['valid']
                        else:
                            self.error = "%s is invalid" % name
    
    
    class StringField(Field):
    
        REGULAR = "^.*$"
    
        def __init__(self, custom_error_dict=None, required=True):
    
            self.custom_error_dict = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
            if custom_error_dict:
                self.custom_error_dict.update(custom_error_dict)
    
            self.required = required
    
            super(StringField, self).__init__()
    
    
    class IPField(Field):
    
        REGULAR = "^(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}$"
    
        def __init__(self, custom_error_dict=None, required=True):
    
            self.custom_error_dict = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
            if custom_error_dict:
                self.custom_error_dict.update(custom_error_dict)
    
            self.required = required
            super(IPField, self).__init__()
    
    
    class EmailField(Field):
    
        REGULAR = "^w+([-+.']w+)*@w+([-.]w+)*.w+([-.]w+)*$"
    
        def __init__(self, custom_error_dict=None, required=True):
    
            self.custom_error_dict = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
            if custom_error_dict:
                self.custom_error_dict.update(custom_error_dict)
    
            self.required = required
            super(EmailField, self).__init__()
    
    
    class IntegerField(Field):
    
        REGULAR = "^d+$"
    
        def __init__(self, custom_error_dict=None, required=True):
    
            self.custom_error_dict = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
            if custom_error_dict:
                self.custom_error_dict.update(custom_error_dict)
    
            self.required = required
            super(IntegerField, self).__init__()
    
    
    class CheckBoxField(Field):
    
        REGULAR = "^d+$"
    
        def __init__(self, custom_error_dict=None, required=True):
    
            self.custom_error_dict = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
            if custom_error_dict:
                self.custom_error_dict.update(custom_error_dict)
    
            self.required = required
            super(CheckBoxField, self).__init__()
    
        def match(self, name, value):
            self.name = name
    
            if not self.required:
                self.is_valid = True
                self.value = value
            else:
                if not value:
                    if self.custom_error_dict.get('required', None):
                        self.error = self.custom_error_dict['required']
                    else:
                        self.error = "%s is required" % name
                else:
                    if isinstance(name, list):
                        self.is_valid = True
                        self.value = value
                    else:
                        if self.custom_error_dict.get('valid', None):
                            self.error = self.custom_error_dict['valid']
                        else:
                            self.error = "%s is invalid" % name
    
    
    class FileField(Field):
    
        REGULAR = "^(w+.pdf)|(w+.mp3)|(w+.py)$"
    
        def __init__(self, custom_error_dict=None, required=True):
    
            self.custom_error_dict = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
            if custom_error_dict:
                self.custom_error_dict.update(custom_error_dict)
    
            self.required = required
    
            super(FileField, self).__init__()
    
        def match(self, name, file_name_list):
            flag = True
            self.name = name
    
            if not self.required:
                self.is_valid = True
                self.value = file_name_list
            else:
                if not file_name_list:
                    if self.custom_error_dict.get('required', None):
                        self.error = self.custom_error_dict['required']
                    else:
                        self.error = "%s is required" % name
                    flag = False
                else:
                    for file_name in file_name_list:
                        if not file_name or not file_name.strip():
                            if self.custom_error_dict.get('required', None):
                                self.error = self.custom_error_dict['required']
                            else:
                                self.error = "%s is required" % name
                            flag = False
                            break
                        else:
                            ret = re.match(self.REGULAR, file_name)
                            if not ret:
                                if self.custom_error_dict.get('valid', None):
                                    self.error = self.custom_error_dict['valid']
                                else:
                                    self.error = "%s is invalid" % name
                                flag = False
                                break
    
                self.is_valid = flag
    
        def save(self, request, upload_to=""):
    
            file_metas = request.files[self.name]
            for meta in file_metas:
                file_name = meta['filename']
                file_path_name = os.path.join(upload_to, file_name)
                with open(file_path_name, 'wb') as up:
                    up.write(meta['body'])
    
            upload_file_path_list = map(lambda path: os.path.join(upload_to, path), self.value)
            self.value = list(upload_file_path_list)
    fields.py

    2、验证文件(继承fields)

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from backend.form import fields
    
    
    class BaseForm:
    
        def __init__(self):
            self._value_dict = {}
            self._error_dict = {}
            self._valid_status = True
    
        def valid(self, handler):
    
            for field_name, field_obj in self.__dict__.items():
                if field_name.startswith('_'):
                    continue
    
                if type(field_obj) == fields.CheckBoxField:
                    post_value = handler.get_arguments(field_name, None)
                elif type(field_obj) == fields.FileField:
                    post_value = []
                    file_list = handler.request.files.get(field_name, [])
                    for file_item in file_list:
                        post_value.append(file_item['filename'])
                else:
                    post_value = handler.get_argument(field_name, None)
    
                field_obj.match(field_name, post_value)
                if field_obj.is_valid:
                    self._value_dict[field_name] = field_obj.value
                else:
                    self._error_dict[field_name] = field_obj.error
                    self._valid_status = False
            return self._valid_status
    forms

    3、自定义类

    注意:self.xxx = yyy(),其中xxx为需要验证的字段,即你再input中定义的name属性的值,右边的为验证的规则,自定义类必须继承验证文件的类

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from backend.form.forms import BaseForm
    from backend.form.fields import StringField
    from backend.form.fields import IntegerField
    
    class LoginForm(BaseForm):
    
        def __init__(self):
            self.user = StringField()
            self.password = StringField()
            self.code = StringField()
            super(LoginForm, self).__init__()
    

    form =  LoginForm(自定义类)() 得到一个对象

    通过 form.valid(self)可以验证用户提交的内容是否通过验证--------必须把self传进去为了获取值

    通过form._value_dict可以获取用户提交的所有内容

    通过form._error_dict可以获取错误信息,用于在前端展示

    发送数据的几种方式

    在一个页面上也许会有增加,修改,和删除等功能,这里可能需要我们需要到一个模板,并提交数据,由于增加和修改的时候,我们所需要的数据大致相同,所以我们可以利用一个模板进行提交数据,而且提交数据的时候我们也可以用同一个ajax进行提交

    ajax提交数据常用的几种方式:

      1、Get是向服务器发索取数据的一种请求

      2、Post是向服务器提交数据的一种请求

      3、Put是向服务器提交修改数据的一种请求

      4、Delete是向服务器提交删除数据的一种请求

    我们可以提前申明一个变量 var METHOD

    当用户点击添加的时候我们把变量赋值为METHOD = 'post';

    当用户点击修改的时候我们把变量赋值为METHOD = 'put';

    当用户点击删除的时候我们把变量赋值为METHOD = 'delete';

    这样我们就不用重复的写ajax,提高了代码的重用性

            ret = JSON.stringify(ret)
            $.ajax({
                type:METHOD,
                url: '/commodity',
                data: {'ret':ret},
                success:function (arg) {
                    location.reload()
                }
            });
    

    ret = JSON.stringify(ret)在JavaScript中用于将字典转换成字符串的格式

    ret =JSON.parse(ret)在JavaScript中用于将字符串转换成字典的格式

  • 相关阅读:
    Asp.net中导出Excel文档(Gridview)
    以太坊难度炸弹是什么?极大抑制矿工继续以POW方式挖矿!
    Solidity语言基础 和 Etherum ERC20合约基础
    BCH/BSV coin split troubleshooting
    比特币学习-Transaction的locktime属性
    在BCH硬分叉后防止重放攻击-2
    在BCH硬分叉后防止重放攻击-1
    区块链硬分叉-软分叉简单了解
    BTC和BCH 区别和联系?
    BCHABC/BCHSV的矛盾所在
  • 原文地址:https://www.cnblogs.com/luxiaojun/p/5872585.html
Copyright © 2011-2022 走看看