zoukankan      html  css  js  c++  java
  • Flask

    werkzurg

    #类似于django wsgiref
    from werkzeug.wrappers import Request, Response
    from werkzeug.serving import run_simple
    
    #实例一
    def run(environ,start_response):
        return [b"asdfasdf"]
    
    if __name__ == '__main__':
        run_simple('localhost', 4000, run)  #请求进来了会加括号执行第三个参数 如果是对象的话 会触发__call__
    
        
    
    示例二:
    from werkzeug.wrappers import Request, Response
    
    @Request.application
    def hello(request):
    	return Response('Hello World!')
    
    if __name__ == '__main__':
        from werkzeug.serving import run_simple
        run_simple('localhost', 4000, hello)		    
    		
    

     flask

    from flask import Flask
    app = Flask(__name__)
    
    @app.route('/index')
    def index():
        return "Hello World"
    
    if __name__ == '__main__':  #防止被导入时候也被运行
        app.run()
    
    from flask import Flask,render_template
    app = Flask(__name__,template_folder='temlates') #在这改的模板文件
    
    @app.route('/index')
    def index():
        return render_template("login.html")  #默认在temlates下找 ,可以在上面修改template默认文件夹
    
    if __name__ == '__main__':  #防止被导入时候也被运行
        app.run()

    登录实例

    from flask import Flask,render_template,request,redirect,session
    app = Flask(__name__,template_folder="templates")
    
    @app.route('/login',methods=["GET","POST"]) #允许提交的method  默认是Get
    def login():
        if request.method == 'GET':
            return render_template('login.html')
        user = request.form.get('user')     #这个request必须导才能使用(上下文管理)form 是post 数据 
        pwd = request.form.get('pwd')       #get 数据在request.args 
        if user == 'oldboy' and pwd == '666':
            session['user'] = user
            return redirect('/index')  #重跳转
        return render_template('login.html',error='用户名或密码错误')  #后端可以拿到这个error {{error}}
        # return render_template('login.html',**{"error":'用户名或密码错误'})
    
    @app.route('/index')
    def index():
        user = session.get('user')
        if not user:
            return redirect('/login')
        return render_template('index.html')
    
    if __name__ == '__main__':
        app.run()
        
    

     模板传递 

    {{ error}}    
    
    传递的时候return  error='sss'    **{error:'ss'} #django 会自动加()   

    <img src='ssss/tupia.png'> #就算有这个sss 也找不到 sss是前缀 static_url_path='/ssss' #可以修改

    app=Flask(static_folder='static') #默认是static下找图片 而图片要的是前缀是ssss的

    登录认证

    from flask import Flask,session
    session["user"]=user
    session["pwd"]=pwd
    
    往cookie里存 session实际上加密的cookie里
    
    app.secret_key='盐' #加盐
    

    配置文件使用

    给你一个路径 字符串的 可以找到类和类的静态字段
    实例 略#

    cookie知道Key 吗? 我们不知道 其实是内部做了 所以我们能session["key"]=v

    app.config #在这里
    怎么修改呢?
    app.config.from_object('配置文件路径')  #比如到线上的配置就是Pro

    class Dev(): #表示开发环境
        kEY=VALUES #小写的没用
       DEVUG=Flase
    class Pro(): #表示线上环境
        kEY=VALUES #小写的没用
      
    DEBUG=True
    app.config.from_object('setting.Dev')  #比如到DEV

    路由系统

    @app.route('/index',method=['GET',"POST"])
    def  index():
        return 'index'
    
    
    起别名
    from filask import url_from
    @app.route('/index',method=['GET',"POST"],endpoint='n1') #重命名  不写默认是函数名
    def  index():
        url_from("n1")  #可以通过url_form  拿到真正的url   
        return 'index'
    

      

    from filask import url_from
    @app.route('/index/<int:nid>',method=['GET',"POST"],endpoint='n1') #不写默认是函数名
    def  index(nid):
        url_from("n1")  #可以通过n1 拿到真正的url   
        return 'index'
    
    
    #支持的有  str  any  path  int float  uuid   #默认 不支持正则
    
    @app.route('/index/<int:nid>',method=['GET',"POST"],endpoint='n1') 
    def  index(nid):
        url_from("n1",nid=nid)  #匹配完整url
        return 'index'
    

    请求和相应相关-视图

    request 的参数
    
    
    
    return的参数
    
    #返回相应体
    字符串
    render_template()
    redicrect  
    jsonify  #内部自动序列化 
    
    
    #返回字符串怎么返回响应体
    obj=make_response(''str')
    obj.headers['xxxx']='123' #头里加东西
    obj.set_cookie(key,value) #设置cookie
    return obj 

     实例 股票管理

    from flask import Flask,render_template,request,redirect,session
    app = Flask(__name__,template_folder="templates")
    app.config.from_object('配置文件路径') 
    STUDENT_DICT={
     1:{'name':'xzq'},
     2:{'ss':'ss'}
    }
    @app.route('/index/<int:nid>',method=['GET',"POST"],endpoint='n1') 
    def  index(nid):
        url_from("n1",nid=nid)  #匹配完整url
        return render_template('dd.html',student_dic=STUDENT_DICT)
    

    模板

    tr #一行
    th 表题
    td       普通内容
    tbody  内容体
    theader 
    
    
    {% for  k,v  in  stu_dic.items() %}
    <tr>
    <td>{{  v['name'] }}</td>  # v.name 也能拿到  v.get('name',默认值) 
    </tr>
    
    <a href='del/{{k}}'>  #删除
    
    {%  endfor  %}

    
    

     

    装饰器的坑
    如果使用装饰器 如果再用反向解析 就不知道哪个是哪个了
    因为所有的view都是一个inner
    
    装饰器导入顺序
    从下到下
    

      

    装饰器不适合批量

    应用场景:比较少的
    
    
    第三版本:before_request  #用于执行真正视图函数之前 进行一个拦截 进行判断
    @app.before_require
    def xxxx():
        xxx   
    
    
    @app.before_require
    def xxxx():
        xxx   
        #return   xxx    #如果返回立即返回不走后面的视图    
    
    页面看到的就是 xxx
    

      

     模板

    {{ list.0 }}  #索引取值方式一
    {{ list[0] }} #索引取值方式二
    {{ text }}  #如果传递过来的是html   还是文本
     {{ text|safe }}  #如果传递过来的是html   还是文本
    
    #Python 用Markup  相当于makesafe
    
    {{ func}}  #函数地址
    {{ func(7)}}  #返回值
    
    
    默认返回所有值
    @app.template_global()
    def sb(a1,a2):
        return a1+a2
    
    
    @app.template_filter():
    def db(a1,a2,a3):
        return a1+a2+a3
    {{1|db(2,3)}}  #这个返回值可以对其if判断
    
    
    模板继承
    {% extens 'layout.html' %}
    {% end%}
    
    
    定义宏  相当于定义函数
      {% macro ccc(name,type='text',value='')%}
          <h1>宏</h1>
          <input type="{{type}}" name="{{name}}" value="{{value}}">
          <input type="submit" value="提交">
      {% endmacro %}
    
    
      {{ ccc('n1') }}
      {{ ccc('n2') }}
    
    
    基本数据类型  可以执行Python语法  

    session

    请求刚进来就创建一个空的字典
    每次处理 都会内存拿那个字典
    当要返回的时候 加密返回
    
    返回前段的session的键  
    配置文件可以修改
    SESSION_REFERSH_EACH_REQUEST #每次请求超时时间往后推 
    

      

    闪现

    在session中存储一个数据,读取时通过pop将数据移除。

    flash('临时数据存储','error')  # 值,分类
    get_flashed_messages() # [  '存储']
    get_flashed_messages()  #[]   
    
    print(get_flashed_messages(category_filter=['error']))  #通过category_filter 取error的分类里找

    flask启动

    请求进来了 会触发app下的__call__ 方法
    
    怎么在请求之前做一个操作,call方法执行之后执行一个操作
    
    重改 app.wsgi_app 
    class Middleware(object):
        def __init__(self, old):
            self.old = old
    
        def __call__(self, *args, **kwargs):
            print('前')
            ret = self.old(*args, **kwargs)
            print('后')
            return ret
    
    
    if __name__ == '__main__':
        app.wsgi_app = Middleware(app.wsgi_app)
        app.run()
        # app.__call__  # 请求来了才执行__call__方法
    

    特殊的装饰器

    @app.befer_request
    def x1():
        print("after")
        
    
    
    @app.after_request
    def x2(response):
         return response
    
    
    
    before #先定义限制性
    
    after  #后往上执行
    

       

    @app.before_first_request   #flask 启动执行第一次请求
    
    @app。errorhandle(404)
    def not_found(arg):
        return '没找到'
    

    路由设置的两种方式

    def index():
    	return "index"
    app.add_url_rule("/xxx",None,index)
    			
    

    - 不用让endpoint重名
    - 如果重名函数也一定要相同。

    参数

    b. 参数 
    			rule,                       URL规则
    			view_func,                  视图函数名称
    			endpoint=None,              名称,用于反向生成URL,即: url_for('名称')
    			methods=None,               允许的请求方式,如:["GET","POST"]
    			strict_slashes=None,        对URL最后的 / 符号是否严格要求, False  即可baidu.com/1 也可以 baidu.com/1/
    			redirect_to=None,           重定向到指定地址,例如 开发完新系统后 应该重定向到新地址,而不是使用新的url redirect_to="xxx/"
    			defaults=None,              默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
    			subdomain=None,             子域名访问
    

      

    from flask import Flask, views, url_for
    
    app = Flask(import_name=__name__)
    app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
    """
    127.0.0.1   wupeiqi.com
    127.0.0.1   web.wupeiqi.com
    127.0.0.1   admin.wupeiqi.com
    
    """
    
    # http://admin.wupeiqi.com:5000/ 才能访问
    @app.route("/", subdomain="admin")
    def admin_index():
        return "admin.your-domain.tld"
    
    
    # http://web.wupeiqi.com:5000/
    @app.route("/", subdomain="web")
    def web_index():
        return "web.your-domain.tld"
    
    
    # http://sdsdf.wupeiqi.com:5000/
    # http://sdfsdf.wupeiqi.com:5000/
    # http://asdf.wupeiqi.com:5000/
    
    @app.route("/dynamic", subdomain="<username>")
    def username_index(username):
        """Dynamic subdomains are also supported
        Try going to user1.your-domain.tld/dynamic"""
        return username + ".your-domain.tld"
    
    
    if __name__ == '__main__':
        app.run()

    CBV

    import functools
    from flask import Flask,views
    app = Flask(__name__)
    
    
    def wrapper(func):
        @functools.wraps(func)
        def inner(*args,**kwargs):
            return func(*args,**kwargs)
    
        return inner
    
    
    
    class UserView(views.MethodView):
        methods = ['GET']  #只支持GET 请求
        decorators = [wrapper,] #给每个函数加装饰器
    
        def get(self,*args,**kwargs):
            return 'GET'
    
        def post(self,*args,**kwargs):
            return 'POST'
    
    app.add_url_rule('/user',None,UserView.as_view('uuuu'))  #uuu 就是endpoint
    
    if __name__ == '__main__':
        app.run()

    自定义路由 (略)

    from flask import Flask,url_for
    
    app = Flask(__name__)
    
    # 步骤一:定制类
    from werkzeug.routing import BaseConverter
    class RegexConverter(BaseConverter):
    	"""
    	自定义URL匹配正则表达式
    	"""
    
    	def __init__(self, map, regex):
    		super(RegexConverter, self).__init__(map)
    		self.regex = regex
    
    	def to_python(self, value):
    		"""
    		路由匹配时,匹配成功后传递给视图函数中参数的值
    		:param value:
    		:return:
    		"""
    		return int(value)
    
    	def to_url(self, value):
    		"""
    		使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
    		:param value:
    		:return:
    		"""
    		val = super(RegexConverter, self).to_url(value)
    		return val
    
    # 步骤二:添加到转换器
    app.url_map.converters['reg'] = RegexConverter
    
    """
    1. 用户发送请求
    2. flask内部进行正则匹配
    3. 调用to_python(正则匹配的结果)方法
    4. to_python方法的返回值会交给视图函数的参数
    
    """
    
    # 步骤三:使用自定义正则
    @app.route('/index/<reg("d+"):nid>')
    def index(nid):
    	print(nid,type(nid))
    
    	print(url_for('index',nid=987))
    	return "index"
    
    if __name__ == '__main__':
    	app.run()
    

    session实现原理(源码) 08

    蓝图(给开发者提供目录结构)16-09

    #counter 视图
    from flask import Blueprint,render_template
    
    ac = Blueprint('ac',__name__)
    
    @ac.before_request
    def x1():
        print('app.before_request')
    
    
    @ac.route('/login')
    def login():
        return render_template('login.html')
    
    
    @ac.route('/logout')
    def logout():
        return 'Logout'
    
    #user 视图
    from flask import Blueprint
    
    uc = Blueprint('uc',__name__)
    
    
    @uc.route('/list')
    def list():
        return 'List'
    
    
    @uc.route('/detail')
    def detail():
        return 'detail'
    
    #__init__  注册蓝图
    from flask import Flask
    from .views.account import ac
    from .views.user import uc
    
    def create_app():
    
        app = Flask(__name__)
    
        app.register_blueprint(ac)
        app.register_blueprint(uc,url_prefix='/api')
        return app
    

      

    manage.py

    from crm import create_app
    
    app = create_app()
    
    if __name__ == '__main__':
        app.run()

    自定义静态文件和模板路径

    ac = Blueprint('ac',__name__,template_folder ='',static_url_path='')   

    加前缀 -有点像路由分发

    app.register_blueprint(uc,url_prefix='/uc') #user/login

    给蓝图加before_request 就相当于在局部才触发

    from flask import Blueprint
    
    uc = Blueprint('uc',__name__)
    
    @uc.before_request  #只在局部加装饰器
    def x1():
        xxxx
    
    @uc.route('/login')
    def login():
        xxx  

    threading.local【和flask无任何关系】 16-12

    上下文管理 16-13

    箱子 :{
    线程id:{ctx:ctx 对象},
    线程id2:{ctx:ctx 对象},
    }
    
    视图函数:
    from flask  import request 
    
    
     请求结束后 根据线程唯一标识 移除空调上的数据上  

    上下文管理

    - 面向对象中特殊方法 setattr/getattr注意事项:

    class Foo(object):
    def __init__(self):
        # self.storage = {}
        object.__setattr__(self,'storage',{})  #不能再init 的时候通过.的方式赋值
    
        def __setattr__(self, key, value):
            print(key,value,self.storage)
    
    obj = Foo()
    obj.xx = 123
        

    基于列表实现的栈

    class Stack(object):
    
        def __init__(self):
            self.data = []
    
        def push(self,val):
            self.data.append(val)
    
        def pop(self):
            return self.data.pop()
        
        def top(self):
            return self.data[-1]
    
    _stack = Stack()
    
    _stack.push('佳俊')
    _stack.push('咸鱼')
    
    print(_stack.pop())
    print(_stack.pop())

    Local 对象(原理)

    try:
        from greenlet import getcurrent as get_ident
    except:
        from threading import get_ident
    
    """
    class Local(object):
        
        def __init__(self):
            object.__setattr__(self,'storage',{})  #创建一个线程  定义一个空字典
        
        def __setattr__(self, key, value):
            ident = get_ident()   #获取表示
            if ident not in self.storage:
                self.storage[ident] = {key:value} #如果这个表示不存在的话 就创建这个
            else:
                self.storage[ident][key] = value   #如果这个表示存在的话  修改
                
        def __getattr__(self, item):
            ident = get_ident()
            if ident in self.storage:              #有的话 返回这个
                return self.storage[ident].get(item)
    """  

    人家的local

    __slots__  #规定了只能点哪些属性
    
    local 做了数据隔离、
    class Local(object):
        __slots__ = ('__storage__', '__ident_func__')
    
        def __init__(self):
            # __storage__ = {1231:{'stack':[]}}
            object.__setattr__(self, '__storage__', {})
            object.__setattr__(self, '__ident_func__', get_ident)
    
        def __getattr__(self, name):
            try:
                return self.__storage__[self.__ident_func__()][name]
            except KeyError:
                raise AttributeError(name)
    
        def __setattr__(self, name, value):
            ident = self.__ident_func__()
            storage = self.__storage__
            try:
                storage[ident][name] = value
            except KeyError:
                storage[ident] = {name: value}
    
        def __delattr__(self, name):
            try:
                del self.__storage__[self.__ident_func__()][name]
            except KeyError:
                raise AttributeError(name)
    

    flask-session 使用

    pip3 install flask-session

    app.config["session_type"]='redis'
    

      

    - 使用
        # by luffycity.com
        import redis
        from flask import Flask,request,session
        from flask.sessions import SecureCookieSessionInterface
        from flask_session import Session
    
        app = Flask(__name__)
    
        # app.session_interface = SecureCookieSessionInterface()
        # app.session_interface = RedisSessionInterface()
        app.config['SESSION_TYPE'] = 'redis'
        app.config['SESSION_REDIS'] = redis.Redis(host='140.143.227.206',port=6379,password='1234')
        Session(app)
    
        @app.route('/login')
        def login():
            session['user'] = 'alex'
            return 'asdfasfd'
    
        @app.route('/home')
        def index():
            print(session.get('user'))
    
            return '...'
    
    
        if __name__ == '__main__':
            app.run()
    - 原理:
        - session数据保存到redis
            session:随机字符串1:q23asifaksdfkajsdfasdf
            session:随机字符串2:q23asifaksdfkajsdfasdf
            session:随机字符串3:q23asifaksdfkajsdfasdf
            session:随机字符串4:q23asifaksdfkajsdfasdf
            session:随机字符串5:q23asifaksdfkajsdfasdf
        - 随机字符串返回给用户。
            随机字符串和 

     work——home

     

     

    代码统计用户列表 18-04

    数据库连接池DBUTILS 18-10

    setting

    pip3 install DBUtils
    
    
    setting
    from DBUtils.PooledDB import PooledDB, SharedDBConnection
    import pymysql
    
    class Config(object):
        SALT = b"sdf1123df"
        SECRET_KEY = 'asdf123sdfsdfsdf'
        MAX_CONTENT_LENGTH = 1024 * 1024 * 7
    
    
        POOL = PooledDB(
            creator=pymysql,  # 使用链接数据库的模块
            maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
            mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
            maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
            maxshared=3,
            # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
            blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
            maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
            setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
            ping=0,
            # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
            host='127.0.0.1',
            port=3306,
            user='root',
            password='123456',
            database='s9day118',
            charset='utf8'
        )
    

     使用

    conn=POOL.connect()
    

      

    handle

    import pymysql
    
    from settings import Config
    
    def connect():
        conn = Config.POOL.connection()
        cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
        return conn,cursor
    
    
    def connect_close(conn,cursor):
        cursor.close()
        conn.close()
    
    def fetch_all(sql,args):
        conn,cursor = connect()
    
        cursor.execute(sql, args)
        record_list = cursor.fetchall()
        connect_close(conn,cursor)
    
        return record_list
    
    
    def fetch_one(sql, args):
        conn, cursor = connect()
        cursor.execute(sql, args)
        result = cursor.fetchone()
        connect_close(conn, cursor)
    
        return result
    
    
    def insert(sql, args):
        conn, cursor = connect()
        row = cursor.execute(sql, args)
        conn.commit()
        connect_close(conn, cursor)
        return row
    

     加锁

    user1 

    mysql  >  begin;
    mysql  >  select * from ss for update ;  #这样才算加锁 有结果

    user  2  

    mysql  >  begin;
    mysql  >  select * from ss for update ;  #阻塞  锁还没释放

    释放锁的操作

    commit;  支持行锁
    indndb 支持行锁

    各个框架加锁

    wtforms

    pip3 install wtforms
    
    from flask import Flask,request,render_template,session,current_app,g,redirect
    from wtforms import Form
    from wtforms.fields import simple
    from wtforms.fields import html5
    from wtforms.fields import core
    
    from wtforms import widgets
    from wtforms import validators
    
    app = Flask(__name__)
    
    
    class LoginForm(Form):
        name = simple.StringField(   #定义字段类型
            validators=[             #
                validators.DataRequired(message='用户名不能为空.'), #制定规则  
                # validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d')
            ],
            widget=widgets.TextInput(),  #制定input类型
            render_kw={'placeholder':'请输入用户名'}  #增加属性  透明提示 
        )
        pwd = simple.PasswordField(
            validators=[
                validators.DataRequired(message='密码不能为空.'),
                # validators.Length(min=8, message='用户名长度必须大于%(min)d'),
                # validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[$@$!%*?&])[A-Za-zd$@$!%*?&]{8,}",
                #                   message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符')
    
            ],
            render_kw={'placeholder':'请输入密码'}
        )
    
    
    @app.route('/login',methods=['GET','POST'])
    def login():
        if request.method == "GET":
            form = LoginForm()
            # print(form.name,type(form.name)) # form.name是StringField()对象, StringField().__str__
            # print(form.pwd,type(form.pwd))   # form.pwd是PasswordField()对象,PasswordField().__str__
            return render_template('login.html',form=form)  #返回表单
    
        form = LoginForm(formdata=request.form)   #生成有数据表单 
        if form.validate():  #校验
            print(form.data)
            return redirect('https://www.luffycity.com/home')
        else:
            # print(form.errors)
            return render_template('login.html', form=form)
    
    
    class RegisterForm(Form):
        name = simple.StringField(
            label='用户名',
            validators=[
                validators.DataRequired()
            ],
            widget=widgets.TextInput(),
            render_kw={'class': 'form-control'}, #添加属性
            default='alex'  #默认值
        )
    
        pwd = simple.PasswordField(
            label='密码',
            validators=[
                validators.DataRequired(message='密码不能为空.')
            ],
            widget=widgets.PasswordInput(),
            render_kw={'class': 'form-control'}
        )
    
        pwd_confirm = simple.PasswordField(
            label='重复密码',
            validators=[
                validators.DataRequired(message='重复密码不能为空.'),
                validators.EqualTo('pwd', message="两次密码输入不一致")
            ],
            widget=widgets.PasswordInput(),
            render_kw={'class': 'form-control'}
        )
    
        email = html5.EmailField(
            label='邮箱',
            validators=[
                validators.DataRequired(message='邮箱不能为空.'),
                validators.Email(message='邮箱格式错误')
            ],
            widget=widgets.TextInput(input_type='email'),
            render_kw={'class': 'form-control'}
        )
    
        gender = core.RadioField(
            label='性别',
            choices=(
                (1, '男'),
                (2, '女'),
            ),
            coerce=int # int("1")
        )
        city = core.SelectField(
            label='城市',
            choices=(
                ('bj', '北京'),
                ('sh', '上海'),
            )
        )
    
        hobby = core.SelectMultipleField(
            label='爱好',
            choices=(
                (1, '篮球'),
                (2, '足球'),
            ),
            coerce=int
        )
    
        favor = core.SelectMultipleField(
            label='喜好',
            choices=(
                (1, '篮球'),
                (2, '足球'),
            ),
            widget=widgets.ListWidget(prefix_label=False),
            option_widget=widgets.CheckboxInput(),
            coerce=int,
            default=[1, ]
        )
    
    
    
    @app.route('/register', methods=['GET', 'POST'])
    def register():
        if request.method == 'GET':
            form = RegisterForm()
            return render_template('register.html', form=form)
    
        form = RegisterForm(formdata=request.form)
        if form.validate():
            print(form.data)
            return redirect('https://www.luffycity.com/home')
    
        return render_template('register.html', form=form)
    
    import helper
    class UserForm(Form):
        city = core.SelectField(
            label='城市',
            choices=(),
            coerce=int
        )
        name = simple.StringField(label='姓名')
    
        def __init__(self,*args,**kwargs):
            super(UserForm,self).__init__(*args,**kwargs)
    
            self.city.choices=helper.fetch_all('select id,name from tb1',[],type=None)
    
    
    @app.route('/user')
    def user():
        if request.method == "GET":
            #form = UserForm(data={'name':'alex','city':3})
            form = UserForm()
            return render_template('user.html',form=form)
    
    
    if __name__ == '__main__':
        app.run()
    

      

    {{% for  field  in from  %}}
    {{ filed }}
    {{ field.lable }}
    {% endfor %}
    
    
    默认选中
    favor = core.SelectMultipleField(
            label='喜好',
            choices=(
                (1, '篮球'),
                (2, '足球'),
            ),
            widget=widgets.ListWidget(prefix_label=False),
            option_widget=widgets.CheckboxInput(),
            coerce=int,
            default=[1, ]
        )

    显示错误信息
    {{filed.error[0] }}

     logging

  • 相关阅读:
    面试算法爱好者书籍/OJ推荐
    go语言——数据类型
    go编程规范
    Go语言常见语法错误
    go语言入门
    python——itertools
    linux sed使用
    python——optparse模块
    Linux基本配置
    文件包含
  • 原文地址:https://www.cnblogs.com/xzqpy/p/11675038.html
Copyright © 2011-2022 走看看