Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
PythonWEB¿ò¼ÜÖ®Flask
 
  2924  次浏览      27
 2019-8-1 
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚwww.cnblogs.com£¬ÎÄÕ°¸Àý˵Ã÷£¬´ÓÅäÖÃÎļþ£¬Â·ÓÉϵͳ£¬ÊÓͼ£¬Ä£°åÓïÑԵȽéÉÜÏêϸ¡£

ǰÑÔ£º

Django:1¸öÖØÎäÆ÷£¬°üº¬ÁËweb¿ª·¢Öг£ÓõŦÄÜ¡¢×é¼þµÄ¿ò¼Ü£»£¨ORM¡¢Session¡¢Form¡¢Admin¡¢·ÖÒ³¡¢Öмä¼þ¡¢Ðźš¢»º´æ¡¢ContenType....£©£»

Tornado:2´óÌØÐÔ¾ÍÊÇÒì²½·Ç×èÈû¡¢Ô­ÉúÖ§³ÖWebSocketЭÒ飻

Flask£º·â×°¹¦Äܲ»¼°DjangoÍêÉÆ£¬ÐÔÄܲ»¼°Tornado£¬µ«ÊÇFlaskµÄµÚÈý·½¿ªÔ´×é¼þ±È·á¸»£»http://flask.pocoo.org/extensions/

Bottle£º±È½Ï¼òµ¥£»

×ܽ᣺

¶¼²»ÊÇÎÒдµÄ£¡£¡£¡²»ÂÛÓÅÁÓ£¬²»Í¬µÄ¹¤¾ß¶øÒÑ£»

СÐÍwebÓ¦ÓÃÉè¼ÆµÄ¹¦Äܵ㲻¶àʹÓÃFlask£»

´óÐÍwebÓ¦ÓÃÉè¼ÆµÄ¹¦Äܵã±È½Ï¶àʹÓõÄ×é¼þÒ²»á±È½Ï¶à£¬Ê¹ÓÃDjango£¨×Ô´ø¹¦Äܶ಻ÓÃÈ¥ÕÒ²å¼þ£©£»

Èç¹û×·ÇóÐÔÄÜ¿ÉÒÔ¿¼ÂÇTornado£»

FlaskµÄsocketÊÇ»ùÓÚWerkzeug ʵÏֵģ¬Ä£°åÓïÑÔÒÀÀµjinja2Ä£°å£¬ÔÚʹÓÃFlask֮ǰÐèÒª°²×°Ò»Ï£»

pip3 install flask #°²×°flask

from werkzeug.wrappers import Request, Response # FlaskµÄsocketʹÓÃwerkzeugʵÏÖ£¬ËùÒÔÒªµ¼Èë werkzeug

@Request.application

def hellow(request):
return Response('Hello World')

if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple('localhost',400,hellow)

Flask¼òµ¥Ê¹ÓÃ

from flask import Flask

app=Flask(__name__) #´´½¨1¸öFlaskʵÀý

@app.route('/') #·ÓÉϵͳÉú³É ÊÓͼ¶ÔÓ¦url,1. decorator=app.route() 2. decorator(first_flask)
def first_flask(): #ÊÓͼº¯Êý
return 'Hello World' #response


if __name__ == '__main__':
app.run() #Æô¶¯socket


Ò»¡¢ÅäÖÃÎļþ

app=Flask (__name__, template_folder ='templates', static_url_path ='/static/',static_path ='/zhanggen')

Ä£°å·¾¶£º template_folder='templates'

¾²Ì¬Îļþ·¾¶£ºstatic_url_path='/static/'

¾²Ì¬ÎļþÒýÈë±ðÃû£ºstatic_path='/zhanggen'

ÉèÖÃΪµ÷ÊÔ»·¾³£ºapp.debug=True £¨´úÂëÐÞ¸Ä×Ô¶¯¸üУ©

ÉèÖÃjson±àÂë¸ñʽ Èç¹ûΪFalse ¾Í²»Ê¹ÓÃascii±àÂ룺app.config['JSON_AS_ASCII']=False

ÉèÖÃÏìӦͷÐÅÏ¢Content-Type app.config['JSONIFY_MIMETYPE'] ="application/json;charset=utf-8" £¨×¢Òâ ;charset=utf-8£©

¶þ¡¢Â·ÓÉϵͳ

1.¶¯Ì¬Â·ÓÉ£¨url´«²Î£©

@app.route('/user/<name>')

from flask import Flask

app=Flask(__name__)

@app.route('/<name>') #ÉèÖÃurl´«²ÎÊý http://127.0.0.1:5000/zhanggen
def first_flask(name): #ÊÓͼ±ØÐëÓжÔÓ¦½ÓÊÕ²ÎÊý
print(name)
return 'Hello World' #response


if __name__ == '__main__':
app.run()

@app.route('/post/<int:age>'))

½ÓÊÕÕûÐÍÊý×Ö²ÎÊý
app=Flask(__name__)
@app.route('/<int:age>/') #ÉèÖÃurl´«²ÎÊý http://127.0.0.1:5000/18/
def first_flask(age): #ÊÓͼ±ØÐëÓжÔÓ¦½ÓÊÕ²ÎÊý
print(age)
return 'Hello World' #response

if __name__ == '__main__':
app.run()

 

@app.route('/post/<float:salary>')

#½ÓÊÕ¸¡µãÐÍÐÍÊý×Ö²ÎÊý
app=Flask(__name__)
@app.route('/<float:salary>/') #ÉèÖÃurl´«²ÎÊýhttp://127.0.0.1:5000/2345555.8889/
def first_flask(salary): #ÊÓͼ±ØÐëÓжÔÓ¦½ÓÊÕ²ÎÊý
print(salary)
return 'Hello World' #response

if __name__ == '__main__':
app.run()

 

@app.route('/post/<path:path>')

# ½ÓÊÕURLÁ´½ÓÀàÐͲÎÊý
app=Flask(__name__)
@app.route('/<path:url>/') #ÉèÖÃurl´«²ÎÊý£ºhttp://127.0.0.1:5000/http://www.baiu.com/
def first_flask(url): #ÊÓͼ±ØÐëÓжÔÓ¦½ÓÊÕ²ÎÊý
print(url)
return 'Hello World' #response

if __name__ == '__main__':
app.run()

2¡¢Ö¸¶¨ÔÊÐíµÄÇëÇó·½·¨

@app.route('/login', methods=['GET', 'POST'])

# Ö¸¶¨ÔÊÐíµÄÇëÇó·½·¨
app=Flask(__name__)
@app.route('/<path:url>/',methods=['get']) #Ö»ÔÊÐígetÇëÇó
def first_flask(url):
print(url)
return 'Hello World' #response

if __name__ == '__main__':
app.run()

3¡¢Í¨¹ý±ðÃû·´ÏòÉú³Éurl

#·´ÏòÉú³Éurl
from flask import Flask,url_for
app=Flask(__name__)
@app.route('/<path:url>',endpoint='name1')
def first_flask(url):
print(url_for('name1',url=url)) #Èç¹ûÉèÖÃÁËurl²ÎÊý£¬url_for£¨±ðÃû,¼Ó²ÎÊý£©
return 'Hello World'

if __name__ == '__main__':
app.run()

4¡¢Í¨¹ýapp.add_url_rule()µ÷Ó÷ÓÉ

#·½Ê½2ͨ¹ýapp.add_url_rule()·½·¨µÄ·½Ê½µ÷Ó÷ÓÉ
app=Flask(__name__)

def first_flask():
return 'Hello World'

app.add_url_rule(rule='/index/', endpoint='name1', view_func=first_flask, methods=['GET'])
#app.add_url_rule(rule=·ÃÎʵÄurl, endpoint=·ÓɱðÃû, view_func=ÊÓͼÃû³Æ, methods=[ÔÊÐí·ÃÎʵķ½·¨])
if __name__ == '__main__':
app.run()

5¡¢À©Õ¹Â·Óɹ¦ÄÜ£ºÕýÔòÆ¥Åäurl

Èç¹ûÐèҪһЩ¸´Ôӵį¥Å乿Ôò¿ÉÒÔ×Ô¶¨ÒåÕýÔòÆ¥Åäurl

from flask import Flask, views, url_for
from werkzeug.routing import BaseConverter

app = Flask(import_name=__name__)


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ÖеIJÎÊý
:param value:
:return:
"""
val = super(RegexConverter, self).to_url(value)
return val

# Ìí¼Óµ½flaskÖÐ
app.url_map.converters['regex'] = RegexConverter


@app.route('/index/<regex("\d+"):nid>')
def index(nid):
print(url_for('index', nid='888'))
return 'Index'


if __name__ == '__main__':
app.run()

ËÄ¡¢ÊÓͼ

1¡¢¸øFlaskÊÓͼº¯Êý¼Ó×°ÊÎÆ÷

×¢ÒâÈç¹ûÒª¸øÊÓͼº¯Êý¼Ó×°ÊÎÆ÷Ôö¼Óй¦ÄÜ£¬Ò»µãÒª¼ÓÔÚ·ÓÉ×°ÊÎÆ÷ÏÂÃæ£¬²Å»á±»Â·ÓÉ×°ÊÎÆ÷×°ÊΣ¬²ÅÄÜÉúÉú³Éurl¹ØÏµ£»

#¸øFlaskÊÓͼ¼Ó×°ÊÎÆ÷
#1¡¢¶¨Òå1¸ö×°ÊÎÆ÷

def auth(func):
print('ÎÒÔÚÉÏÃæ')
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner


app=Flask(__name__)

@app.route('/',methods=['GET'])
@auth #×¢ÒâÈç¹ûÒª¸øÊÓͼº¯Êý¼Ó×°ÊÎÆ÷£¬Ò»µãÒª¼ÓÔÚ·ÓÉ×°ÊÎÆ÷ÏÂÃæ£¬²Å»á±»Â·ÓÉ×°ÊÎÆ÷×°ÊÎ
def first_flask():
print('ffff')
return 'Hello World'

if __name__ == '__main__':
app.run()

2¡¢requestºÍresponse

a.ÇëÇóÏà¹ØÐÅÏ¢

request.method£º »ñÈ¡ÇëÇó·½·¨

request.json

request.json.get("json_key")£º»ñÈ¡jsonÊý¾Ý **½Ï³£ÓÃ

request.argsget('name') £º»ñÈ¡getÇëÇó²ÎÊý

request.form.get('name') £º»ñÈ¡POSTÇëÇó²ÎÊý

request.form.getlist('name_list')£º»ñÈ¡POSTÇëÇó²ÎÊýÁÐ±í£¨¶à¸ö£©

request.values.get('age') £º»ñÈ¡GETºÍPOSTÇëÇóЯ´øµÄËùÓвÎÊý£¨GET/POSTͨÓã©

request.cookies.get('name')£º»ñÈ¡cookiesÐÅÏ¢

request.headers.get('Host')£º»ñÈ¡ÇëÇóÍ·Ïà¹ØÐÅÏ¢

request.path£º»ñÈ¡Óû§·ÃÎʵÄurlµØÖ·£¬ÀýÈ磨/£¬/login/£¬/ index/£©£»

request.full_path£º»ñÈ¡Óû§·ÃÎʵÄÍêÕûurlµØÖ·+²ÎÊý ÀýÈç(/login/?age=18)

request.script_root£º ±§Ç¸£¬ÔÝδÀí½âÆäº¬Ò壻

request.url£º»ñÈ¡·ÃÎÊurlµØÖ·£¬ÀýÈçhttp://127.0.0.1:5000/?age=18£»

request.base_url£º»ñÈ¡·ÃÎÊurlµØÖ·£¬ÀýÈç http://127.0.0.1:5000/£»

request.url_root

request.host_url

request.host£º»ñÈ¡Ö÷»úµØÖ·

request.files£º»ñÈ¡Óû§ÉÏ´«µÄÎļþ

obj = request.files['the_file_name']

obj.save('/var/www/uploads/' + secure_filename(f.filename)) Ö±½Ó±£´æ

b¡¢ÏìÓ¦Ïà¹ØÐÅÏ¢

return "×Ö·û´®" £ºÏìÓ¦×Ö·û´®

return render_template('htmlÄ£°å·¾¶',**{})£ºÏìӦģ°å

return redirect('/index.html')£ºÌø×ªÒ³Ãæ

ÏìÓ¦jsonÊý¾Ý

·½Ê½1£º return jsonify(user_list)

app.config['JSON_AS_ASCII']= False #Ö¸¶¨json±àÂë¸ñʽ Èç¹ûΪFalse ¾Í²»Ê¹ÓÃascii±àÂ룬
app.config['JSONIFY_MIMETYPE'] = "application/json;charset =utf-8" #Ö¸¶¨ä¯ÀÀÆ÷äÖȾµÄÎļþÀàÐÍ£¬ºÍ½âÂë¸ñʽ£»

 

·½Ê½2£º

return Response(data,mimetype="application/json;charset=utf-8",)

Èç¹ûÐèÒªÉèÖÃÏìӦͷ¾ÍÐèÒª½èÖúmake_response()·½·¨

from flask import Flask, request,make_response

response = make_response(render_template('index.html'))

responseÊÇflask.wrappers.ResponseÀàÐÍ

response.delete_cookie('key')

response.set_cookie('key', 'value')

response.headers['X-Something'] = 'A value'

return respons

3 ¡¢FlaskÖ®CBVÊÓͼ

#CBVÊÓͼ
from flask import Flask,url_for,views

app=Flask(__name__) #×°ÊÎÆ÷

def auth(func):
print('ÎÒÔÚÉÏÃæ')
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner

class IndexView(views.MethodView): #CBVÊÓͼ
methods=['GET'] #ÔÊÐíµÄhttpÇëÇó·½·¨£¨¸ÄCBVÖ»ÔÊÐíGET·½·¨£©
decorators = [auth,] #ÿ´ÎÇëÇó¹ýÀ´¶¼¼Óauth×°ÊÎÆ÷

def get(self):
return 'Index.GET'
def post(self):
return 'Index.POST'

app.add_url_rule('/index/', view_func= IndexView.as_view (name='name1')) # (name='name1'·´ÏòÉú³Éurl±ðÃû


if __name__ == '__main__':
app.run()

Î塢ģ°åÓïÑÔ

FlaskʹÓõÄÊÇJinja2Ä£°å£¬ËùÒÔÆäÓï·¨ºÍDjangoÎÞ²î±ð£¨DjangoµÄÄ£°åÓïÑԲο¼Jinja2£©

1.ÒýÓþ²Ì¬Îļþ

·½Ê½1£º±ðÃûÒýÈë

<link rel="stylesheet" href="/zhanggen/commons.css">

·½Ê½2£ºurl_for()·½·¨ÒýÈë

<link rel="stylesheet" href="{{ url_for('static', filename='commons.css') }}">

2.Ä£°åÓïÑÔÒýÓÃÉÏÏÂÎĶÔÏó

±äÁ¿

<h1>{{user_list}}</h1> <!--±äÁ¿ -->

 

Ñ­»·¡¢Ë÷Òýȡֵ

<ul>
{% for user in user_list %} <!--Ñ­»· -->
<li>{{user}}</li>
{% endfor %}

{{user_list.0}} <!-- Ë÷Òýȡֵ-->

</ul>

 

FlaskµÄJinjia2¿ÉÒÔͨ¹ýContext °ÑÊÓͼÖеĺ¯Êý´«µÝ°ÑÄ£°åÓïÑÔÖÐÖ´ÐУ¬Õâ¾ÍÊÇDjangoÖеÄsimple_tagºÍsimple_fifter£»

simple_tag£¨Ö»ÄÜ´«2¸ö²ÎÊý,Ö§³Öfor¡¢if£©

@app.template_global() #simple_tag
def foo(arg):
return '<input type="text">'

<h1>{{foo(1)|safe}}</h1>

simple_fifter£¨¶Ô²ÎÊý¸öÊýÎÞÏÞÖÆ£¬²»Ö§³Öfor¡¢if£©

@app.template_filter() #simple_fifter
def foo1(arg1,arg2,arg3):
return arg1+arg2+arg3

<h1> {{ 'alex'|foo1('s ','b',) }} </h1> <!-- simple_fifter -->

3.wtform£¨flask±íµ¥ÑéÖ¤²å¼þ£©

3.0.¼ò½é

wtforms WTFormsÊÇÒ»¸öÖ§³Ö¶à¸öweb¿ò¼ÜµÄform×é¼þ£¬Ö÷Òª¶ÔÓû§ÇëÇóÊý¾Ý ½øÐÐ±íµ¥ÑéÖ¤¡£

3.1. °²×°

pip install wtforms #°²×°wtfroms²å¼þ

 

3.2.¼òµ¥Ê¹ÓÃ

wtformsºÍDjango×Ô´øµÄformÑéÖ¤²å¼þ¹¦ÄÜÏàͬ£¬Ê¹ÓÃÆðÀ´´óͬСÒ죻

Óû§µÇÂ¼Ò³ÃæÑéÖ¤

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets


app=Flask(__name__,template_folder='templates') #ÖªµÀÄ£°åÎļþ
app.debug=True

#µÇ¼Ñé֤ʵÀý
class LoginForm(Form):

#²»Í¬µÄ×Ö¶Î ÄÚ²¿°üº¬ÕýÔò±í´ïʽ html5.EmailField | html5.DateTimeField...
name=simple.StringField(
label='Óû§Ãû',
validators=[ #ÑéÖ¤¹æÔòºÍ´íÎóÌáʾÐÅÏ¢
validators.DataRequired(message='Óû§Ãû²»ÄÜΪ¿Õ.'),
validators.Length(min=6, max=18, message='Óû§Ãû³¤¶È±ØÐë´óÓÚ%(min)dÇÒСÓÚ%(max)d')
],
widget=widgets.TextInput(), #ǰ¶ËÒ³ÃæÏÔʾµÄ²å¼þ.TextArea
render_kw={'class': 'form-control'} #ÉèÖÃform±êÇ©µÄclassÐÅÏ¢

)

# ²»Í¬µÄ×Ö¶Î ÄÚ²¿°üº¬ÕýÔò±í´ïʽ html5.EmailField | html5.DateTimeField...
pwd = simple.PasswordField(
label='ÃÜÂë',
validators=[
validators.DataRequired(message='ÃÜÂë²»ÄÜΪ¿Õ.'),
validators.Length(min=8, message='Óû§Ãû³¤¶È±ØÐë´óÓÚ%(min)d'),
#×Ô¶¨ÒåÑéÖ¤¹æÔò
validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,}",
message='ÃÜÂëÖÁÉÙ8¸ö×Ö·û£¬ÖÁÉÙ1¸ö´óд×Öĸ£¬1¸öСд×Öĸ£¬1¸öÊý×ÖºÍ1¸öÌØÊâ×Ö·û')

],
widget=widgets.PasswordInput(),
render_kw={'class': 'form-control'}
)

@app.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
form = LoginForm() #ʵÀý»¯ formÑéÖ¤Àà
return render_template('login.html', form=form)
else:
form = LoginForm(formdata=request.form)
if form.validate(): #ÅжÏÊÇ·ñÑéÖ¤³É¹¦£¿
print('Óû§Ìá½»Êý¾Ýͨ¹ý¸ñʽÑéÖ¤£¬Ìá½»µÄֵΪ£º', form.data)
else:
print(form.errors)
return render_template('login.html', form=form)

if __name__ == '__main__':
app.run()


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>怬</h1>
<form method="post" novalidate>
<!--<input type="text" name="name">-->
<p>{{form.name.label}} {{form.name}} {{form.name.errors[0] }}</p>

<!--<input type="password" name="pwd">-->
<p>{{form.pwd.label}} {{form.pwd}} {{form.pwd.errors[0] }}</p>
<input type="submit" value="Ìá½»">
</form>
</body>
</html>

login.html

 

Óû§×¢²áÒ³ÃæÑéÖ¤

#Óû§×¢²á
from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets

app = Flask(__name__, template_folder='templates')
app.debug = True

class RegisterForm(Form):
name = simple.StringField(
label='Óû§Ãû',
validators=[
validators.DataRequired()
],
widget=widgets.TextInput(),
render_kw={'class': 'form-control'},
default='ÕŸù' #ÉèÖÃinput±êÇ©ÖÐĬÈÏÖµ
)

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="Á½´ÎÃÜÂëÊäÈë²»Ò»ÖÂ") #ÑéÖ¤2´ÎÊäÈëµÄÃÜÂëÊÇ·ñÒ»Ö£¿
],
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'), #Éú³Éemail input±êÇ©
render_kw={'class': 'form-control'}
)

gender = core.RadioField(
label='ÐÔ±ð',
choices=( #choice radioÑ¡Ïî
(1, 'ÄÐ'),
(2, 'Å®'),
),
coerce=int #½²Óû§Ìá½»¹ýÀ´µÄ '4' Ç¿ÖÆ×ª³É int 4
)
city = core.SelectField(
label='³ÇÊÐ',
choices=(
('bj', '±±¾©'),
('sh', 'ÉϺ£'),
)
)

hobby = core.SelectMultipleField( #select ÏÂÀ­¿ò¶àÑ¡¿ò
label='°®ºÃ',
choices=(
(1, 'ÀºÇò'),
(2, '×ãÇò'),
),
coerce=int
)

favor = core.SelectMultipleField(
label='ϲºÃ',
choices=(
(1, 'ÀºÇò'),
(2, '×ãÇò'),
),
widget=widgets.ListWidget(prefix_label=False), #Éú³ÉCheckbox ¶àÑ¡¿ò
option_widget=widgets.CheckboxInput(),
coerce=int,
default=[1, 2]
)

def __init__(self, *args, **kwargs): #ÖØÐ´formÑéÖ¤ÀàµÄ__init__·½·¨¿ÉÒÔʵʱͬ²½Êý¾ÝÖÐÊý¾Ý
super(RegisterForm, self).__init__(*args, **kwargs)
self.favor.choices = ((1, 'ÀºÇò'), (2, '×ãÇò'), (3, 'ÓðëÇò'))


def validate_pwd_confirm(self, field): #wtformsÑéÖ¤ ¹³×Óº¯Êý
"""
×Ô¶¨Òåpwd_confirm×ֶιæÔò£¬Àý£ºÓëpwd×Ö¶ÎÊÇ·ñÒ»ÖÂ
:param field:
:return:
"""
# ×ʼ³õʼ»¯Ê±£¬self.dataÖÐÒѾ­ÓÐËùÓеÄÖµ

if field.data != self.data['pwd']:
# raise validators.ValidationError("ÃÜÂë²»Ò»ÖÂ") # ¼ÌÐøºóÐøÑéÖ¤
raise validators.StopValidation("ÃÜÂë²»Ò»ÖÂ") # ²»ÔÙ¼ÌÐøºóÐøÑéÖ¤


@app.route('/register/', methods=['GET', 'POST'])
def register():
if request.method == 'GET':
form = RegisterForm(data={'gender': 1}) #ĬÈÏÖµ
return render_template('register.html', form=form)
else:
form = RegisterForm(formdata=request.form)
if form.validate():
print('Óû§Ìá½»Êý¾Ýͨ¹ý¸ñʽÑéÖ¤£¬Ìá½»µÄֵΪ£º', form.data)
else:
print(form.errors)
return render_template('register.html', form=form)

if __name__ == '__main__':
app.run()

 

Hello World!

3.2.wtformsÔ´Âë ²ÂÏë....

A.×Ô¶¯Éú³Éhtml±êÇ©

ÏÈÀ´·ÖÎöÒ»ÏÂformÑéÖ¤ÀàµÄ½á¹¹

LoginFormÀàÖаüº¬ÁË2¸ö×Ö¶Î: name ºÍ pwd£¬¶øname / pwd×Ö¶Î = ¶ÔÏó£¬ËùÒÔLoginForm Àà°üº¬ÁË2¸ö¶ÔÏó£»

Èç¹ûʵÀý»¯ÁËobj=LoginForm() ¾ÍµÈÓÚ ÔÚ Õâ1¸ö¶ÔÏóÖÐǶÌ×ÁË 2¸ö¶ÔÏó£»

ǰ¶ËʹÓÃFormÑéÖ¤²å¼þ£º

ÄÇÈç¹ûÔÚǰ¶ËforÑ­»·LoginForm¶ÔÏ󣬾͵ÈÓÚµ÷ÓÃLoginForm¶ÔÏóµÄ__iter__·½·¨£¬°Ñÿ¸ö×ֶΣ¨¶ÔÏ󣩷â×°µÄÊý¾Ý ·µ»Ø

Èç¹ûǰ¶Ë{{ obj }}= Ö±½Óµ÷ÓÃÁË×ֶζÔÏóµÄ__str__·½·¨£»

class InputText(object): #²å¼þ
def __str__(self):
return '<input type="text" />'

class InputPassword(object):
def __str__(self):
return '<input type="password" />'


class StringField(object): #×Ö¶Î
def __init__(self,wg):
self.widget=wg

def __str__(self): #µ÷Óòå¼þµÄ__str__
return str(self.widget)

class DateField(object):
def __init__(self, wg):
self.widget = wg

def __str__(self):
return str(self.widget)


class LoginForm(object): #ͳһ Áé»î½Ó¿Ú £¨¶ÔÏóǶÌ×¶ÔÏ󣬶à²ã·â×°£©
name=StringField(wg=InputText()) #wg=InputText() ¶ÔÏó StringField(wg=InputText())¶ÔÏó
pwd=DateField(wg=InputPassword())


l_obj=LoginForm()

print(l_obj.name)
print(l_obj.pwd)
¸´ÖÆ´úÂë

B.Êý¾ÝУÑé

ºǫ́¶¨ÒåºÃÕýÔò

Óû§·¢À´Êý¾Ý

¶ÔÊý¾Ý½øÐÐУÑé

3.3.Ô´ÂëÁ÷³Ì

Éú³ÉHTML±êÇ©²¢ÏÔʾ

1.ÑéÖ¤ÀࣨLogibForm£©Éú³É

1.1.ÓÉÓÚ metaclass=FormMeta£¬ËùÒÔLoginFormÊÇÓÉFormMeta´´½¨µÄ

'''
class BaseForm():
pass

class NewBase(BaseForm,metaclass=FormMeta,):
pass

class Form(NewBase):
pass

class LoginForm(Form):
pass

'''

class Form(with_metaclass(FormMeta,BaseForm)):

1.2.Ö´ÐÐFormMeta µÄ__init__·½·¨£¬ÔÚLoginFormÖÐÌí¼Ó2¸ö¾²Ì¬×Ö¶Î

class FormMeta(type):
"""
The metaclass for `Form` and any subclasses of `Form`.

`FormMeta`'s responsibility is to create the `_unbound_fields` list, which
is a list of `UnboundField` instances sorted by their order of
instantiation. The list is created at the first instantiation of the form.
If any fields are added/removed from the form, the list is cleared to be
re-generated on the next instantiation.

Any properties which begin with an underscore or are not `UnboundField`
instances are ignored by the metaclass.
"""
def __init__(cls, name, bases, attrs):
type.__init__(cls, name, bases, attrs) #¼Ì³ÐtypeµÄ¹¦ÄÜ
cls._unbound_fields = None #ÔÚLoginFormÖÐÌí¼Ó1¸ö¾²Ì¬×Ö¶Î
cls._wtforms_meta = None #ÔÚLoginFormÖÐÌí¼Ó1¸ö¾²Ì¬×Ö¶Î

 

1.3.¿ªÊ¼½âÊÍLoginFormÖÐµÄ ÊµÀý»¯×ֶζÔÏóname=simple.StringField(£©simple.PasswordField()

StringField/PasswordField¿ªÊ¼ÊµÀý»¯(ÌᵽʵÀý»¯¾ÍÓ¦¸ÃÏëµ½£ºÖ¸¶¨ÔªÀàµÄ__call__¡¢×Ô¼º/¸¸ÀàµÄ__new__¡¢__init__)£º

StringField/PasswordFieldÊÇĬÈÏÔªÀ࣬×Ô¼ºÃ»ÓÐ__new__ºÍ__init__·½·¨£»

µ«¸¸ÀàFieldÀàÖÐÓÐ__new__·½·¨£¬ËùÒÔÖ´Ðи¸ÀàµÄ__new__£¨Field.__new__£©·µ»ØUnboundField¶ÔÏó


def __new__(cls, *args, **kwargs):#Ö´ÐÐ__new__·½·¨
if '_form' in kwargs and '_name' in kwargs:
return super(Field, cls).__new__(cls)
else:
#ÎÒx ûÏëµ½ ! __new__¼ÈÈ»·µ»ØÁË1¸ö UnboundField()¶ø²»ÊÇStringField/PasswordField¶ÔÏó£»Àêè»»ÁËÌ«×Ó £¿
return UnboundField(cls, *args, **kwargs)

ÓÉÓÚField.__new__·½·¨·µ»ØÁË 1¸ö UnboundField¶ÔÏó£¬À´¿´ UnboundFieldµÄ__init__·½·¨


class UnboundField(object):
_formfield = True
creation_counter = 0 #¾²Ì¬×Ö¶Î ÉèÖüÆÊýÆ÷

def __init__(self, field_class, *args, **kwargs): #field_class=.StringField / PasswordField
#»ñÈ¡µ½field_class µÄ ²ÎÊý·â×°µ½ UnboundField¶ÔÏóÖУ¬²¢ÇÒÉèÖà ÅÅÐò 'creation_counter': 2

UnboundField.creation_counter += 1 #ÿʵÀý»¯1¸ö UnboundField¶ÔÏó ¼ÆÊýÆ÷+1
self.field_class = field_class
self.args = args
self.kwargs = kwargs #{'label': 'Óû§Ãû', 'validators': [<wtforms.validators.DataRequired object at 0x00000000038EF080>, <wtforms.validators.Length object at 0x00000000038EF0F0>], 'widget': <wtforms.widgets.core.TextInput object at 0x00000000038EF0B8>, 'render_kw': {'class': 'form-control'}}
self.creation_counter = UnboundField.creation_counter#

'''
print(self.__dict__)
{
'field_class': <class 'wtforms.fields.simple.PasswordField'>,
'args': (),
'kwargs': {'label': 'ÃÜÂë', 'validators': [<wtforms.validators.DataRequired object at 0x00000000038EF198>, <wtforms.validators.Length object at 0x00000000038EF1D0>, <wtforms.validators.Regexp object at 0x00000000038EF208>], 'widget': <wtforms.widgets.core.PasswordInput object at 0x00000000038EF2B0>,
'render_kw': {'class': 'form-control'}},
'creation_counter': 2
}

'''

 

UnboundFieldµÄ__init__·½·¨ÔÚ UnboundField¶ÔÏóÖзâ×°ÁËFieldÀàµÄ²ÎÊýºÍ¼ÆÊýÆ÷£¬ËùÒÔÏÖÔÚLoginFormlÀàÖзâ×°Êý¾ÝÈçÏÂ

 


"""
print(LoginForm.__dict__)
LoginForm ={
'__module__': '__main__',
'name': <1 UnboundField(StringField, (),{'creation_counter': 1, 'label': 'Óû§Ãû', 'validators': [<wtforms.validators.DataRequired object at 0x00000000037DAEB8>, <wtforms.validators.Length object at 0x000000000382B048>], 'widget': <wtforms.widgets.core.TextInput object at 0x000000000382B080>, 'render_kw': {'class': 'form-control'} })>,
'pwd': <2 UnboundField(PasswordField, (),{'creation_counter': 2,'label': 'ÃÜÂë', 'validators': [<wtforms.validators.DataRequired object at 0x000000000382B0F0>, <wtforms.validators.Length object at 0x000000000382B128>, <wtforms.validators.Regexp object at 0x000000000382B160>], 'widget': <wtforms.widgets.core.PasswordInput object at 0x000000000382B208>, 'render_kw': {'class': 'form-control'}})>,
'__doc__': None,
'_unbound_fields': None,
'_wtforms_meta': None,
}
"""

Æô·¢£º

²»Ò»¶¨Òª°Ñ´úÂ붼дÔÚµ±Ç°ÀàÖУ¬Èç¹ý¶à¸öÀàºÍÀàÖ®¼äÓÐͬÐÔ·½·¨¡¢ÊôÐÔ¿ÉÒÔ³é³öÀ´¼¯Öе½¸¸ÀàÖ®ÖУ»×ÓÀà¼Ì³Ð¸¸ÀàËùÒÔ×ÓÀàʵÀý»¯¶ÔÏóÖ®ºó£¬¼Ì³ÐÏíÓÐ2ÕßµÄÊôÐԺͷ½·¨£»ËùÒÔ¿´Ô´ÂëÓöµ½¼Ì³ÐÒ»µãҪעÒ⠹۲츸Àࣻ

ÿ¸ö¶ÔÏóʵÀý»¯£¨ÔÚÅųýMetaClassµÄÇé¿öÏ£©¶¼»áÖ´ÐÐ ¸¸ÀàµÄ__new__·½·¨£¬ÔÙÈ¥Ö´ÐÐ__init__·½·¨£»¶ø__new__ʵÖÊÐÔ¾ö¶¨ÁËʵÀý»¯³öÀ´µÄ¶ÔÏóÊÇÉñÂí£¿

class Queen(object):
def __new__(cls, *args, **kwargs): #ÀàÖÐ__new__·½·¨¾ö¶¨ÁËÀࣨ£©£¬ÊµÀý»¯³öʲô¶ÔÏó£»
return Cat('Àêè','ÄÐ','Ì«×Ó')

def __init__(self,name): #ÓÉÓÚ__nwe__·½·¨·µ»ØÁËÆäËû¶ÔÏó£¬ËùÒÔ²»»áÖ´ÐÐQueenµÄ__init__·½·¨
print('ok')
self.name=name

Prince=Queen('Íõ×Ó')
print(Prince.name)
print(Prince.gender)
print(Prince.identity)

 

2.LoginFormʵÀý»¯

̸µ½ÀàʵÀý»¯Ó¦¸ÃÏȼì²é¸ÃÀàÊÇ·ñÖ¸¶¨ÁË MetaÀ࣬Èç¹ûÖ¸¶¨ÁËMetaÀ࣬ ¾ÍÐèÒªÏÈÖ´ÐÐ £¨Ö¸¶¨ÔªÀàµÄ__call__¡¢×Ô¼º/¸¸ÀàµÄ__new__¡¢__init__)

21.Ö´ÐÐFormMetaµÄ__call__·½·¨£¬¸³ÖµLoginFormµÄ_unbound_fields ºÍ _wtforms_metaÊôÐÔ£»

¸ù¾Ýunbound¶ÔÏóµÄcreation_counterÊôÐÔ¶Ô LoginFormÖеÄ×ֶνøÐÐÅÅÐò£¬²¢Ìî³äµ½ LoginFormµÄ_unbound_fieldsÊôÐÔÖÐ

¸ù¾Ý LoginFormµÄ__mro__¼Ì³Ð˳Ðò£º»ñÈ¡µ±Ç°ÀࣨFormLogin£©ËùÓи¸Àà,²¢ÔÚÿ¸ö¸¸ÀàÖÐ ÌáÈ¡MetaÊôÐÔÌí¼Óµ½ÁÐ±í£¬×ª³ÉÔª×飬×îºó´´½¨MetaÀàÈÃÆä¼Ì³Ð£¬¸³ÖµLoginForm._wtforms_metaÊôÐÔ

def __call__(cls, *args, **kwargs):
if cls._unbound_fields is None: #ÔÚ´´½¨Ààʱ ÒѾ­ÉèÖÃLoginFormµÄ_unbound_fieldsΪ¿Õ
fields = []
# »ñÈ¡LoginFormÀàÖУ¬ÖÐËùÓÐÊôÐÔµÄkey£º[ '_get_translations', '_unbound_fields', '_wtforms_met,'name', 'populate_obj', 'process', 'pwd', 'validate'..... ]
for name in dir(cls):
if not name.startswith('_'): #Åųý__Ï»®ÏßµÄ˽ÓÐÊôÐÔ name. pwd
unbound_field = getattr(cls, name) #cls =LoginFormÀà #¸ù¾Ýkey »ñÈ¡unbound_field ¶ÔÏó
if hasattr(unbound_field, '_formfield'): #¼ì²éunbound_field ¶ÔÏóÊÇ·ñ°üº¬_formfield = True
fields.append((name, unbound_field))
# '''
# fields = [
# (name,nameµÄunbound¶ÔÏó),
# (pwd,pwdµÄunbound¶ÔÏó),
# ]
# '''
#¶Ôfields °´ÕÕ¶¨Òå˳Ðò ½øÐÐÅÅÐò
fields.sort(key=lambda x: (x[1].creation_counter, x[0])) #¸ù¾Ýunbound¶ÔÏóµÄcreation_counter½øÐÐ×Ö¶ÎÅÅÐò
cls._unbound_fields = fields

if cls._wtforms_meta is None:
bases = [] #bases = [DefaultMeta],
# °´Õռ̳Ð˳Ðò£º»ñÈ¡µ±Ç°ÀࣨFormLogin£©ËùÓи¸Àà
for mro_class in cls.__mro__:
if 'Meta' in mro_class.__dict__: #ȥÿ¸ö¸¸Àࣨmro_class£©»ñÈ¡ Meta = DefaultMeta


bases.append(mro_class.Meta) #bases = [DefaultMeta],

'''
class Meta(DefaultMeta):
pass
'''
cls._wtforms_meta = type('Meta', tuple(bases), {}) #cls._wtforms_meta=Meta(DefaultMeta)Àà:

return type.__call__(cls, *args, **kwargs)

 

Ö´ÐÐÍêÁËÖ¸¶¨ÔªÀà FormMeta.__call__()·½·¨Ö®ºóµÄLoginFormÀàÖзâ×°µÄÊý¾Ý

print(LoginForm.__dict__)
LoginForm ={
'__module__': '__main__',
'name': <1 UnboundField(StringField, (),{'creation_counter': 1, 'label': 'Óû§Ãû', 'validators': [<wtforms.validators.DataRequired object at 0x00000000037DAEB8>, <wtforms.validators.Length object at 0x000000000382B048>], 'widget': <wtforms.widgets.core.TextInput object at 0x000000000382B080>, 'render_kw': {'class': 'form-control'} })>,
'pwd': <2 UnboundField(PasswordField, (),{'creation_counter': 2,'label': 'ÃÜÂë', 'validators': [<wtforms.validators.DataRequired object at 0x000000000382B0F0>, <wtforms.validators.Length object at 0x000000000382B128>, <wtforms.validators.Regexp object at 0x000000000382B160>], 'widget': <wtforms.widgets.core.PasswordInput object at 0x000000000382B208>, 'render_kw': {'class': 'form-control'}})>,
'__doc__': None,

'_unbound_fields': [
(name, UnboundField¶ÔÏó£¨1£¬simple.StringField£¬²ÎÊý£©)£¬
(pwd, UnboundField¶ÔÏó£¨2£¬simple.PasswordField£¬²ÎÊý£©)£¬
],,
'_wtforms_meta': Meta(DefaultMeta)Àà,
}
"""

 

 

Æô·¢£º

#sortÅÅÐò
v1=[
(11,'Martin11',18),
(121,'Martin121',19),
(311,'Martin311',25),
(311, 'Martin311', 26) #°´ÔªËØ1ÅÅÐò£¬Èç¹ûÔªËØ1Ïàͬ°´ÕÕ ÔªËØ3ÅÅÐò
]

v1.sort(key=lambda x:(x[0],x[2])) #ÁбíµÄsort·½·¨£¬¸ù¾Ý ÁбíÖеÄÔª×éÔªËØ ½øÐÐÅÅÐò
print(v1)
'''

[(11, 'Martin11', 18), (121, 'Martin121', 19), (311, 'Martin311', 25), (311, 'Martin311', 26)]
'''

 

class F1(object):
pass
class F2(object):
pass
class F3(F1):
pass

class F4(F2,F3):
pass

print(F4.__mro__) #´òÓ¡F4 µÄ¼Ì³Ð¹ØÏµ

'''
(
<class '__main__.F4'>,
<class '__main__.F2'>,
<class '__main__.F3'>,
<class '__main__.F1'>,
<class 'object'>)


'''


'''

2.2.Ö´ÐÐLoginFormµÄ__new__·½·¨

ûÓÐ__new__·½·¨ pass

2.3.Ö´ÐÐLoginFormµÄ__init__·½·¨ÊµÀý»¯form¶ÔÏó

def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs):

# ʵÀý»¯LoginFormÖзâ×°µÄ MetaÀà½øÐÐʵÀý»¯£¬ÒÔºóÓÃÓÚÉú³ÉCSRF Tocken ±êÇ©
meta_obj = self._wtforms_meta()
#metaÊÇ form = LoginForm(meta={'csrf':'true'})´«¹ýÀ´µÄ²ÎÊý,·â×°µ½meta_objÖÐ
if meta is not None and isinstance(meta, dict):
meta_obj.update_values(meta)

#Ö´Ðи¸ÀàµÄ¹¹Ôì·½·¨,²ÎÊý
# self._unbound_fields
'''
'_unbound_fields'=[
(name, UnboundField¶ÔÏó£¨1£¬simple.StringField£¬²ÎÊý£©)£¬
(pwd, UnboundField¶ÔÏó£¨2£¬simple.PasswordField£¬²ÎÊý£©)£¬
],
'''
# meta_ob=Meta(DefaultMeta)¶ÔÏó

super(Form, self).__init__(self._unbound_fields, meta=meta_obj, prefix=prefix)
#¸ø form¶ÔÏó ÖеÄ_fields×ֶθ³ÖµÈçÏ£»
'''
_fields: {
name: StringField¶ÔÏó(),
pwd: PasswordField¶ÔÏó(),
}
name: StringField¶ÔÏó(widget=widgets.TextInput()),
pwd: PasswordField¶ÔÏó(widget=widgets.PasswordInput())

'''
#Ñ­»·form¶ÔÏó ÖеÄ_fields×ֶΣ¨×ֵ䣩£¬¸øform¶ÔÏó¸³Öµ form.name/form.pwd
for name, field in iteritems(self._fields):
setattr(self, name, field)
'''
_fields: {
name: StringField¶ÔÏó(),
pwd: PasswordField¶ÔÏó(),
}
name: StringField¶ÔÏó(widget=widgets.TextInput()),

pwd: PasswordField¶ÔÏó(widget=widgets.PasswordInput())

'''
self.process(formdata, obj, data=data, **kwargs)
¸´ÖÆ´úÂë

 

Ö´ÐÐForm¸¸ÀàBaseForm.__init__·½·¨£¬°ÑUnboundField¶ÔÏóת»»³ÉStringField¶ÔÏ󣬲¢¸³Öµµ½form¶ÔÏóµÄ_fields:{}×ÖµäÖУ»

class BaseForm(object):
def __init__(self, fields, prefix='', meta=DefaultMeta()):
'''
²ÎÊý
fields=[
(name, UnboundField¶ÔÏó£¨1£¬simple.StringField£¬²ÎÊý£©)£¬
(pwd, UnboundField¶ÔÏó£¨2£¬simple.PasswordField£¬²ÎÊý£©)£¬
]£¬

meta=Meta(DefaultMeta)¶ÔÏó
'''

if prefix and prefix[-1] not in '-_;:/.':
prefix += '-'

self.meta = meta
self._prefix = prefix
self._errors = None
self._fields = OrderedDict()

if hasattr(fields, 'items'):
fields = fields.items()

translations = self._get_translations()
extra_fields = []
#------------------------------------------------------
if meta.csrf: #Éú³É CSRF tockenÒþ²Ø±êÇ©
self._csrf = meta.build_csrf(self)
extra_fields.extend(self._csrf.setup_form(self))

for name, unbound_field in itertools.chain(fields, extra_fields):#
#(name, UnboundField¶ÔÏó£¨1£¬simple.StringField£¬²ÎÊý£©)
#(pwd, UnboundField¶ÔÏó£¨2£¬simple.PasswordField£¬²ÎÊý£©)
options = dict(name=name, prefix=prefix, translations=translations)
#(name, UnboundField¶ÔÏó£¨1£¬simple.StringField£¬²ÎÊý£©) #ÕæÕýʵÀý»¯ simple.StringField(²ÎÊý)
field = meta.bind_field(self, unbound_field, options)
#UnboundField¶ÔÏóת»»³ÉStringField¶ÔÏó
self._fields[name] = field

 

form = {
_fields: {
name: StringField¶ÔÏó(),
pwd: PasswordField¶ÔÏó(),
}

Ñ­»·form¶ÔÏó ÖеÄ_fields×ֶΣ¨×ֵ䣩£¬·Ö±ð¸³Öµµ½form¶ÔÏó£¬ÕâÑù¾Í¿ÉÒÔͨ¹ýform.name/form.pwdÖ±½Ó»ñÈ¡µ½Field¶ÔÏóÁË

£¬ÎÞÐèform._fields['name'] / form._fields['name']

´úÂë:

for name, field in iteritems(self._fields):
setattr(self, name, field)

 

 

form¶ÔÏó·â×°Êý¾Ý¾Í±ä³ÉÒÔÏÂÄÚÈÝà¶

form = {
_fields: {
name: StringField¶ÔÏó(),
pwd: PasswordField¶ÔÏó(),
}
name: StringField¶ÔÏó(widget=widgets.TextInput()),
pwd: PasswordField¶ÔÏó(widget=widgets.PasswordInput())

}

 

3. µ±form¶ÔÏóÉú³ÉÖ®ºó print(form.name) = Ö´ÐÐStringField¶ÔÏóµÄ__str__·½·¨£»

StringFieldÀàÖÐûÓÐ__str__·½·¨£¬ËùÒÔÈ¥Ö´ÐлùÀàFieldµÄ£¬Field.__str__·½·¨·µ»ØÁË£º self() = StringFieldObj.__call__()

def __str__(self):
return self() #Ö´ÐÐLoginFormµÄ__call__·½·¨

 

StringFieldûÓÐ__call__ËùÒÔÖ´ÐÐÆä»ùÀàField.__call__·½·¨£¬µ÷ÓÃÁËself.meta.render_field(self, kwargs)

def __call__(self, **kwargs): ¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡# self=StringField¶ÔÏó
return self.meta.render_field(self, kwargs) #°ÑStringField¶ÔÏó´«´«Èëmeta.render_field·½·¨

ÏÂÃæÀ´¿´self.meta.render_field(self, kwargs)×öÁËʲô£¿

def render_field(self, field, render_kw):

other_kw = getattr(field, 'render_kw', None)
if other_kw is not None:
render_kw = dict(other_kw, **render_kw)
# StringField¶ÔÏó.widget(field, **render_kw)
#²å¼þ.__call__()
'''
#field =StringField¶ÔÏó
StringField¶ÔÏó.widget¶ÔÏó()=µ÷ÓÃwidget¶ÔÏóµÄ.__call__·½·¨
'''
return field.widget(field, **render_kw)

 

À´¿´widget¶ÔÏó=TextInput()µÄ__call__·½·¨£¬×îÖÕ´òÓ¡ÁËobj.nameµÄ½á¹û

def __call__(self, field, **kwargs):
kwargs.setdefault('id', field.id)
kwargs.setdefault('type', self.input_type)
if 'value' not in kwargs:
kwargs['value'] = field._value()
if 'required' not in kwargs and 'required' in getattr(field, 'flags', []):
kwargs['required'] = True
return HTMLString('<input %s>' % self.html_params(name=field.name, **kwargs))

 

"""
0. Form.__iter__: ·µ»ØËùÓÐ×ֶζÔÏó
1. StringField¶ÔÏó.__str__
2. StringField¶ÔÏó.__call__
3. meta.render_field(StringField¶ÔÏó,)
4. StringField¶ÔÏó.widget(field, **render_kw)
5. ²å¼þ.__call__()
"""

4.Ö´ÐÐfor iteam in form¶ÔÏóµÄÖ´ÐÐÁ÷³Ì

Ö´ÐÐform¶ÔÏó»ùÀàBaseFormµÄ__inter__·½·¨£¬±äÁ¿self._fields×ÖµäÖеÄÄÚÈÝ

def __iter__(self):
"""Iterate form fields in creation order."""
return iter(itervalues(self._fields))
_fields: {
name: StringField¶ÔÏó(),
pwd: PasswordField¶ÔÏó(),
}

Óû§ÊäÈëÊý¾ÝµÄУÑéÑéÖ¤Á÷³Ìform = LoginForm(formdata=request.form)

# ÇëÇó·¢¹ýÀ´µÄÖµ
form = LoginForm(formdata=request.form) # Öµ.getlist('name')

# ʵÀý£º±à¼­
# # ´ÓÊý¾Ý¿â¶ÔÏó
# form = LoginForm(obj='Öµ') # Öµ.name/Öµ.pwd
#
# # ×Öµä {}
# form = LoginForm(data=request.form) # Öµ['name']

# 1. Ñ­»·ËùÓеÄ×Ö¶Î
# 2. »ñȡÿ¸ö×ֶεĹ³×Óº¯Êý
# 3. Ϊÿ¸ö×Ö¶ÎÖ´ÐÐËûµÄÑéÖ¤Á÷³Ì ×Ö¶Î.validate(¹³×Óº¯Êý+ÄÚÖÃÑéÖ¤¹æÔò)

Áù¡¢session¹¦ÄÜ

1. Flask×Ô´øµÄsession¹¦ÄÜ

from flask import session
import json
app=Flask(__name__, template_folder='templates', static_path='/static/',static_url_path='/static/')
app.debug=True
app.secret_key='sjehfjeefrjewth43u' #ÉèÖÃsession¼ÓÃÜ
app.config['JSON_AS_ASCII'] =False #Ö¸¶¨json±àÂë¸ñʽ Èç¹ûΪFalse ¾Í²»Ê¹ÓÃascii±àÂ룬
app.config['JSONIFY_MIMETYPE'] = "application/json;charset= utf-8" #Ö¸¶¨ä¯ÀÀÆ÷äÖȾµÄÎļþÀàÐÍ£¬ºÍ½âÂë¸ñʽ£»

@app.route('/login/',methods=['GET','POST'])
def login():
msg = ''
if request.method=='POST':
name=request.values.get('user')
pwd=request.values.get('pwd')
if name =='zhanggen' and pwd=='123.com':
session['user']=name #ÉèÖÃsessionµÄkey value
return redirect('/index/')
else:
msg='Óû§Ãû»òÕßÃÜÂë´íÎó'
return render_template('login.html',msg=msg)

@app.route('/index/',methods=['GET','POST'])
def index():
user_list = ['ÕŸù', 'egon', 'eric']
user=session.get('user') #»ñÈ¡session
if user:
user=['alex','egon','eric']
return jsonify(user_list)
else:
return redirect('/login/')

if __name__ == '__main__':
app.run()

 

2.µÚÈý·½session×é¼þ£¨Session£©

°²×° pip install flask-session

from flask import session, Flask,request, make_response,render_template, redirect,jsonify,Response

from flask.ext.session import Session #ÒýÈëµÚÈý·½session
import json
app=Flask(__name__,template_folder= 'templates',static_path= '/static/',static_url_path='/static/')
app.debug=True
app.secret_key='sjehfjeefrjewth43u' #ÉèÖÃsession¼ÓÃÜ
app.config['JSON_AS_ASCII']=False #Ö¸¶¨json±àÂë¸ñʽ Èç¹ûΪFalse ¾Í²»Ê¹ÓÃascii±àÂ룬
app.config['JSONIFY_MIMETYPE'] =& quot;application/json; charset=utf-8" #Ö¸¶¨ä¯ÀÀÆ÷äÖȾµÄÎļþÀàÐÍ£¬ºÍ½âÂë¸ñʽ£»

app.config['SESSION_TYPE']='redis'

from redis import Redis #ÒýÈëÁ¬½Ó redisÄ£¿é
app.config['SESSION_REDIS']= Redis(host='192.168.0.94',port=6379) #Á¬½Óredis
Session(app)

@app.route ('/login/',methods=['GET','POST'])
def login():
msg = ''
if request.method=='POST':
name=request.values.get('user')
pwd=request.values.get('pwd')
if name == 'zhanggen' and pwd=='123.com':
session['user']= name #ÉèÖÃsessionµÄkey value
return redirect('/index/')
else:
msg='Óû§Ãû»òÕßÃÜÂë´íÎó'
return render_template('login.html',msg=msg)

@app.route('/index/',methods=['GET','POST'])
def index():
user_list = ['ÕŸù', 'egon', 'eric']
user=session.get('user') #»ñÈ¡session
if user:
user=['alex','egon','eric']
return jsonify(user_list)
else:
return redirect('/login/')

if __name__ == '__main__':
app.run()

²»½ö¿ÉÒÔ°Ñsession´æ·Åµ½redis»¹¿É·Åµ½Îļþ¡¢ÄÚ´æ¡¢memcache...

def _get_interface(self, app):
config = app.config.copy()
config.setdefault('SESSION_TYPE', 'null')
config.setdefault('SESSION_PERMANENT', True)
config.setdefault('SESSION_USE_SIGNER', False)
config.setdefault('SESSION_KEY_PREFIX', 'session:')
config.setdefault('SESSION_REDIS', None)
config.setdefault('SESSION_MEMCACHED', None)
config.setdefault('SESSION_FILE_DIR',
os.path.join(os.getcwd(), 'flask_session'))
config.setdefault('SESSION_FILE_THRESHOLD', 500)
config.setdefault('SESSION_FILE_MODE', 384)
config.setdefault('SESSION_MONGODB', None)
config.setdefault('SESSION_MONGODB_DB', 'flask_session')
config.setdefault('SESSION_MONGODB_COLLECT', 'sessions')
config.setdefault('SESSION_SQLALCHEMY', None)
config.setdefault('SESSION_SQLALCHEMY_TABLE', 'sessions')

if config['SESSION_TYPE'] == 'redis':
session_interface = RedisSessionInterface(
config['SESSION_REDIS'], config['SESSION_KEY_PREFIX'],
config['SESSION_USE_SIGNER'], config['SESSION_PERMANENT'])
elif config['SESSION_TYPE'] == 'memcached':
session_interface = MemcachedSessionInterface(
config['SESSION_MEMCACHED'], config['SESSION_KEY_PREFIX'],
config['SESSION_USE_SIGNER'], config['SESSION_PERMANENT'])
elif config['SESSION_TYPE'] == 'filesystem':
session_interface = FileSystemSessionInterface(
config['SESSION_FILE_DIR'], config['SESSION_FILE_THRESHOLD'],
config['SESSION_FILE_MODE'], config['SESSION_KEY_PREFIX'],
config['SESSION_USE_SIGNER'], config['SESSION_PERMANENT'])
elif config['SESSION_TYPE'] == 'mongodb':
session_interface = MongoDBSessionInterface(
config['SESSION_MONGODB'], config['SESSION_MONGODB_DB'],
config['SESSION_MONGODB_COLLECT'],
config['SESSION_KEY_PREFIX'], config['SESSION_USE_SIGNER'],
config['SESSION_PERMANENT'])
elif config['SESSION_TYPE'] == 'sqlalchemy':
session_interface = SqlAlchemySessionInterface(
app, config['SESSION_SQLALCHEMY'],
config['SESSION_SQLALCHEMY_TABLE'],
config['SESSION_KEY_PREFIX'], config['SESSION_USE_SIGNER'],
config['SESSION_PERMANENT'])
else:
session_interface = NullSessionInterface()

return session_interface

3.×Ô¶¨Òåsession×é¼þ

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import uuid
import json
from flask.sessions import SessionInterface
from flask.sessions import SessionMixin
from itsdangerous import Signer, BadSignature, want_bytes


class MySession(dict, SessionMixin):
def __init__(self, initial=None, sid=None):
self.sid = sid
self.initial = initial
super(MySession, self).__init__(initial or ())

def __setitem__(self, key, value):
super(MySession, self).__setitem__(key, value)

def __getitem__(self, item):
return super(MySession, self).__getitem__(item)

def __delitem__(self, key):
super(MySession, self).__delitem__(key)


class MySessionInterface(SessionInterface):
session_class = MySession
container = {}

def __init__(self):
import redis
self.redis = redis.Redis()

def _generate_sid(self):
return str(uuid.uuid4())

def _get_signer(self, app):
if not app.secret_key:
return None
return Signer(app.secret_key, salt='flask-session',
key_derivation='hmac')

def open_session(self, app, request):
"""
³ÌÐò¸ÕÆô¶¯Ê±Ö´ÐУ¬ÐèÒª·µ»ØÒ»¸ösession¶ÔÏó
"""
sid = request.cookies.get(app.session_cookie_name)
if not sid:
sid = self._generate_sid()
return self.session_class(sid=sid)

signer = self._get_signer(app)
try:
sid_as_bytes = signer.unsign(sid)
sid = sid_as_bytes.decode()
except BadSignature:
sid = self._generate_sid()
return self.session_class(sid=sid)

# session±£´æÔÚredisÖÐ
# val = self.redis.get(sid)
# session±£´æÔÚÄÚ´æÖÐ
val = self.container.get(sid)

if val is not None:
try:
data = json.loads(val)
return self.session_class(data, sid=sid)
except:
return self.session_class(sid=sid)
return self.session_class(sid=sid)

def save_session(self, app, session, response):
"""
³ÌÐò½áÊøÇ°Ö´ÐУ¬¿ÉÒÔ±£´æsessionÖÐËùÓеÄÖµ
È磺
±£´æµ½resit
дÈëµ½Óû§cookie
"""
domain = self.get_cookie_domain(app)
path = self.get_cookie_path(app)
httponly = self.get_cookie_httponly(app)
secure = self.get_cookie_secure(app)
expires = self.get_expiration_time(app, session)

val = json.dumps(dict(session))

# session±£´æÔÚredisÖÐ
# self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)
# session±£´æÔÚÄÚ´æÖÐ
self.container.setdefault(session.sid, val)

session_id = self._get_signer(app).sign(want_bytes(session.sid))

response.set_cookie(app.session_cookie_name, session_id,
expires=expires, httponly=httponly,
domain=domain, path=path, secure=secure)


from flask import Flask
from flask import session
from my_session import MySessionInterface

app = Flask(__name__)

app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
app.session_interface = MySessionInterface()


@app.route('/login/', methods=['GET', "POST"])
def login():
print(session)
session['user1'] = 'alex'
session['user2'] = 'alex'
del session['user2']

return "ÄÚÈÝ"


if __name__ == '__main__':
app.run()

Æß¡¢À¶Í¼

ʹÓÃFlask×Ô´øBlueprintmukÄ£¿é£¬°ïÖúÎÒÃÇ×ö´úÂëĿ¼½á¹¹µÄ¹éÀà

import luffy #µ¼Èëluffy°ü¾Í»áÖ´ÐÐluffy°üÖÐ__init__.pyÎļþ

luffy.app.run()


from flask import Flask

app=Flask(__name__,template_folder= 'templates',static_path= '/static/',static_url_path='/static/')

app.debug=True


from .views import login
from .views import index

#°ÑÎļþÖÐÀ¶Í¼¶ÔÏó×¢²áµ½appÀï
app.register_blueprint (login.login,url_prefix='/login') #·ÃÎÊloginÀ¶Í¼±ØÐëÒÔurl_prefix¿ªÍ·
app.register_blueprint (index.index,url_prefix='/index')

if __name__ == '__main__':
app.run()


from flask import Blueprint #µ¼ÈëÀ¶Í¼
login=Blueprint('login',__name__) #ÔÚ±¾Ä£¿éʵÀý»¯1¸öÀ¶Í¼

@login.route('/login/',methods=['GET','POST'])
def login1():
return 'µÇÂ¼Ò³Ãæ'


from flask import Blueprint
index=Blueprint('index',__name__)
@index.route('/index/',methods=['GET','POST'])
def index1():
return 'Ê×Ò³'

°Ë¡¢message £¨ÉÁÏÖ£©

messageÊÇÒ»¸ö»ùÓÚSessionʵÏÖµÄÓÃÓÚ±£´æÊý¾ÝµÄ¼¯ºÏ£¬ÆäÌØµãÊÇ£ºÒ»´ÎÐÔ¡£

ÌØµã£ººÍlabadaÄäÃûº¯ÊýÒ»Ñù²»³¤ÆÚÕ¼ÓÃÄÚ´æ

from flask import Flask,request,flash,get_flashed_messages

app = Flask(__name__)
app.secret_key = 'some_secret'


@app.route('/set/')
def index2():
flash('Disposable') #ÔÚmessageÖÐÉèÖÃ1¸ö¸öÖµ
return 'ok'

@app.route('/')
def index1():
messages = get_flashed_messages() #»ñÈ¡messageÖÐÉèÖõÄÖµ£¬Ö»ÄÜ»ñÈ¡1´Î¡££¨1´ÎÐÔ£©
print(messages)
return "Index1"


if __name__ == "__main__":
app.run()

¾Å¡¢Öмä¼þ

flaskÒ²ÓÐÖмä¼þ¹¦ÄܺÍDjangoÀàËÆ£¬²»Í¬µÄÊÇʹÓõÄÊÇʹÓÃ3¸ö×°ÊÎÆ÷À´ÊµÏֵģ»

1.@app.before_first_request :ÇëÇóµÚ1´Îµ½À´Ö´ÐÐ1´Î£¬Ö®ºó¶¼²»Ö´ÐУ»

2.@app.before_request£ºÇëÇóµ½´ïÊÓͼ֮ǰִÐУ»£¨¸Äº¯Êý²»ÄÜÓзµ»ØÖµ£¬·ñÔòÖ±½ÓÔÚµ±Ç°·µ»Ø£©

3.@app.after_request£ºÇëÇó ¾­¹ýÊÓͼ֮ºóÖ´ÐУ»£¨×îÏÂÃæµÄÏÈÖ´ÐУ©

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, Request, render_template

app = Flask(__name__, template_folder='templates')
app.debug = True


@app.before_first_request #µÚ1¸öÇëÇóµ½À´Ö´ÐÐ
def before_first_request1():
print('before_first_request1')


@app.before_request #Öмä¼þ2
def before_request1():
Request.nnn = 123
print('before_request1') #²»ÄÜÓзµ»ØÖµ£¬Ò»µ©Óзµ»ØÖµÔÚµ±Ç°·µ»Ø


@app.before_request
def before_request2():
print('before_request2')

@app.errorhandler(404)
def page_not_found(error):
return 'This page does not exist', 404

@app.route('/')
def hello_world():
return "Hello World"

@app.after_request #Öмä¼þ Ö´ÐÐÊÓͼ֮ºó
def after_request1(response):
print('after_request1', response)
return response


@app.after_request #Öмä¼þ Ö´ÐÐÊÓͼ֮ºó ÏÈÖ´ÐÐ after_request2
def after_request2(response):
print('after_request2', response)
return response

if __name__ == '__main__':
app.run()

Ê®¡¢FlaskÏà¹Ø×é¼þ

1¡¢flask-sqlchemy

2¡¢flask-script×é¼þ

flask-script×é¼þ£ºÓÃÓÚͨ¹ý½Å±¾µÄÐÎʽ£¬Æô¶¯ flask£»£¨ÊµÏÖÀàËÆDjangoµÄpython manager.py runserver 0.0.0.0:8001)

pip install flask-script #°²×°

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from sansa import create_app
from flask_script import Manager #µ¼Èë
app = create_app()

manager=Manager(app) #ʵÀý»¯Manager¶ÔÏó

if __name__ == '__main__':
manager.run()

 

python run.py runserver -h 0.0.0.0 -p 8001

* Running on http://0.0.0.0:8001/ (Press CTRL+C to quit)

3.flask-migrate×é¼þ

ÔÚÏßÐ޸ġ¢Ç¨ÒÆÊý¾Ý¿â£¨DjangoµÄ migrate ¡£

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from sansa import create_app,db
from flask_script import Manager #µ¼Èë
from flask_migrate import Migrate,MigrateCommand

app = create_app()
manager=Manager(app) #ʵÀý»¯Manager¶ÔÏó
migrate=Migrate(app,db)

manager.add_command('db',MigrateCommand) #×¢²áÃüÁî

if __name__ == '__main__':
manager.run()

 

pip install flask-migrate #°²×°

 

3.1.³õʼ»¯Êý¾Ý¿â£ºpython run.py db init

3.2.Ç¨ÒÆÊý¾Ý£º python run.py db migrate

3.3.Éú³É±í£º python run.py db upgrade

ps:Ð޸ıí½á¹¹ first Ö±½Ó×¢Ê;²Ì¬×ֶδúÂ룬second Ö´ÐÐ python run.py db upgrade.

D:\FlaskÁ·Ï°\sansa>python run.py db init
Creating directory D:\FlaskÁ·Ï°\sansa\migrations ... done
Creating directory D:\FlaskÁ·Ï°\sansa\migrations\versions ... done
Generating D:\FlaskÁ·Ï°\sansa\migrations\alembic.ini ... done
Generating D:\FlaskÁ·Ï°\sansa\migrations\env.py ... done
Generating D:\FlaskÁ·Ï°\sansa\migrations\README ... done
Generating D:\FlaskÁ·Ï°\sansa\migrations\script.py.mako ... done
Please edit configuration/connection/logging settings in 'D:\\FlaskÁ·Ï°\\sansa\\migrations\\alembic.ini' before proceeding.

D:\FlaskÁ·Ï°\sansa>python run.py db migrate
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'users666'
Generating D:\FlaskÁ·Ï°\sansa\migrations \versions\a7f412a8146f_.py ... done

D:\FlaskÁ·Ï°\sansa>python run.py db upgrade
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> a7f412a8146f, empty message

D:\FlaskÁ·Ï°\sansa>

 

 

 
   
2924 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
Ïà¹ØÎĵµ

Android_UI¹Ù·½Éè¼Æ½Ì³Ì
ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
Ïà¹Ø¿Î³Ì

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
Androidϵͳ¿ª·¢
AndroidÓ¦Óÿª·¢
ÊÖ»úÈí¼þ²âÊÔ