天天看點

Flask插件Flask-SessionWTFormsFlask-請求上下文Flask-SQLAlchemyFlask-ScriptFlask-Migrate

Flask-Session

from flask import Flask,views,request,session
from flask_session import Session
from redis import Redis

app=Flask(__name__)
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = Redis(host="127.0.0.1",port=6379)

Session(app)

@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST":
        session["user"] = "123"
        return "post"
    return "get"
if __name__ == '__main__':
    app.run(debug=True)      

View Code

WTForms

from flask import Flask, request, render_template

from wtforms import Form, validators, widgets
from wtforms.fields import simple, core

app = Flask(__name__)


class RegForm(Form):
    username = simple.StringField(
        label="使用者名",
        validators=[
            validators.DataRequired(message="使用者名不能為空"),
        ],
        render_kw={"class": "my_class"}
    )

    pwd = simple.PasswordField(
        label="密碼",
        validators=[
            validators.DataRequired(message="密碼不能為空"),
            validators.length(min=6, max=16, message="長度必須大于等于6,小于等于16")
        ],
        render_kw={"class": "form-control"},
        widget = widgets.PasswordInput(),

    )

    pwd_confim = simple.PasswordField(
        label="确認密碼",
        validators=[
            validators.EqualTo("pwd", message="兩次密碼不一緻"),
            validators.length(min=6, max=16, message="長度必須大于等于6,小于等于16")
        ],
    )

    gender = core.SelectField(
        label="性别",
        choices=(
            (1, "女"),
            (2, "男")
        ),
        default=1,
        coerce=int  # 限制是int類型的
    )

    city = core.RadioField(
        label="城市",
        choices=(
            ("1", "北京"),
            ("2", "上海")
        ),
        default=2,
        coerce=str
    )

    email = simple.StringField(
        label="郵箱",
        validators=[
            validators.DataRequired(message="郵箱不能為空"),
            validators.Email(message="格式不對")
        ]
    )

    hobby = core.SelectMultipleField(
        label="愛好",
        choices=(
            (1, "電影"),
            (2, "音樂"),
            (3, "畫畫"),
            (4, "看書")
        ),
        coerce=int,
        default=(1, 4)

    )

    favor = core.SelectMultipleField(
        label="喜好",
        choices=(
            (1, '籃球'),
            (2, '足球'),
        ),
        widget=widgets.ListWidget(prefix_label=False),
        option_widget=widgets.CheckboxInput(),
        coerce=int,
        default=[1, 2]
    )

    def __init__(self,*args,**kwargs):  #這裡的self是一個RegisterForm對象
        '''重寫__init__方法'''
        super().__init__(*args, **kwargs)  #繼承父類的init方法
        self.favor.choices =((1, '籃球'), (2, '足球'), (3, '羽毛球'))  #吧RegisterForm這個類裡面的favor重新指派

    def validate_pwd_confim(self,field,):
        '''
        自定義pwd_config字段規則,例:與pwd字段是否一緻
        :param field:
        :return:
        '''
        # 最開始初始化時,self.data中已經有所有的值
        if field.data != self.data['pwd']:
            # raise validators.ValidationError("密碼不一緻") # 繼續後續驗證
            raise validators.StopValidation("密碼不一緻")  # 不再繼續後續驗證


class LoginForm(Form):
    username = simple.StringField(
        label="使用者名",
        validators=[
            validators.DataRequired(message="使用者名不能為空"),
            validators.length(min=4, max=8, message="長度必須大于等于4,小于等于8")
        ]
    )

    password = simple.PasswordField(
        label="密碼",
        validators=[
            validators.DataRequired(message="密碼不能為空"),
            validators.length(min=4, max=8, message="長度必須大于等于4,小于等于8")
        ]
    )


@app.route('/register',methods=["GET","POST"])
def register():
    if request.method=="GET":
        form = RegForm(data={'gender': 1})  #預設是1,
        return render_template("register.html",form=form)
    else:
        form = RegForm(formdata=request.form)
        if form.validate():  #判斷是否驗證成功
            print('使用者送出資料通過格式驗證,送出的值為:', form.data)  #所有的正确資訊
        else:
            print(form.errors)  #所有的錯誤資訊
        return render_template('register.html', form=form)



@app.route("/reg", methods=["GET", "POST"])
def reg():
    if request.method == "GET":
        rf = RegForm()
        return render_template("reg.html", rf=rf)
    else:
        rf_data = RegForm(request.form)
        if rf_data.validate():
            print(rf_data.data)
            return "OK"
        else:
            return render_template("reg.html", rf=rf_data)


@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "GET":
        login_form = LoginForm()
        return render_template("login.html", lf=login_form)
    else:
        login_form_data = LoginForm(request.form)
        if login_form_data.validate():
            user = login_form_data.data.get("username")
            return str(user)
        else:
            return render_template("login.html", lf=login_form_data)


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

View Code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="" method="post" novalidate>
    {% for field in rf %}

    <p>{{ field.label }}{{ field }}{{ field.errors[0] }}</p>

    {% endfor %}

    <input type="submit" value="submit">
</form>

<form action="" method="post" novalidate>
    <p>{{ lf.username.label }}{{ lf.username }}{{ lf.username.errors.0 }}</p>
    <p>{{ lf.password.label }}{{ lf.password }}{{ lf.password.errors[0] }}</p>
    <input type="submit" value="submit">
</form>

</body>

</body>
</html>      

View Code

Flask-請求上下文

# 偏函數partial
from functools import partial

def my_sum(a, b):
    print(a)
    print(b)
    return a + b


# new_my_sum = partial(my_sum, 10)
# new_my_sum此時就是下面這樣的
# def my_sum(b):
#     a=10


new_my_sum = partial(my_sum,
                     b=10)  # 位置參數一定要在關鍵字參數前面  不能寫成new_my_sum = partial(my_sum, a=10),如果非要這樣寫,下面就改成res = new_my_sum(b=20)
# new_my_sum此時就是下面這樣的
# def my_sum(b):
#     b=10

res = new_my_sum(20)

print(res)


class My:
    def __call__(self, *args, **kwargs):
        print(666, '__call__')

    def __setattr__(self, key, value):
        print(key, value, '__setattr__')

    def __getattr__(self, item):
        print(item, '__getattr__')

    def __setitem__(self, key, value):
        print(key, value, '__setitem__')

    def __getitem__(self, item):
        print(item, '__getitem__')


a = My()
a()  # 執行__call__
a.name = 'tom'  # 執行__setattr__
a['age'] = 18  # __setitem__
a['name']  # __getitem__
a.qweqwewqe  # __getattr__

# 空間換時間
# 線程安全  Flask上下文機制就是使用的Threading.local
# 線程進來,開辟一個空間給這個線程,線程操作的所有任務,都會複制一份到空間中
from threading import local


class Foo(local):
    pass


print('##############################')

# 棧Stack
class Mystack(object):
    data = []

    def __setattr__(self, key, value):
        self.push(key, value)

    def push(self, key, value):
        self.data.append({key:value})

    def top(self):
        return self.data.pop()


my_stack = Mystack()
my_stack.name = 'tom'
my_stack.name = 'rose'

print(my_stack.data)  #[{'name': 'tom'}, {'name': 'rose'}]


#LocalStack
# import threading
# threading.current_thread().ident #目前線程的ID

import threading
from threading import get_ident #和上面是一樣的
class MyLocalStack(object):
    data=[]
    storage={}

    def push(self, item):
        try:
            self.storage[get_ident()].append(item)
        except:
            self.storage[get_ident()]=[item]

    def top(self):
        return self.storage[get_ident()].pop()

my_local_stack=MyLocalStack()

import time
def go(i):
    my_local_stack.push(i)
    time.sleep(1)
    # my_local_stack.top()

for i in range(5):
    t = threading.Thread(target=go,args=(i,))
    t.start()

print(my_local_stack.storage)


###########
from werkzeug.wrappers import Request, Response
from werkzeug.serving import run_simple


@Request.application
def app(req):
    print(req)
    return Response("200ok")


run_simple("0.0.0.0", 9527, app)

"""
run_simple("0.0.0.0",9527,app)   會執行app函數

from flask import Flask
app=Flask(__name__)

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

"""      

鋪墊

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask,request
app=Flask(__name__)

if __name__ == '__main__':
    app.run()
    #run_simple(host, port, self, **options)
    #app()=obj()=obj.__call__
    #app.wsgi_app


"""
上文
self._local=={"__storage__":{},"__ident_func__":get_ident}
ctx = requestcontext對象  此對象中有 request/session 
此時  self._local=={"__storage__":{3721:{"stack":[ctx] }},"__ident_func__":get_ident}

_request_ctx_stack == LocalStack()==self._local=={"__storage__":{3721:{"stack":[ctx] }},"__ident_func__":get_ident}
"""

"""
下文源碼
request = LocalProxy(partial(_lookup_req_object, "request")#傳回的是request對象)
        

class LocalProxy(object):
    __slots__ = ("__local", "__dict__", "__name__", "__wrapped__")

    def __init__(self, local, name=None):  ####local==request偏函數==partial(_lookup_req_object, "request")#傳回的是request對象
        object.__setattr__(self, "_LocalProxy__local", local)  #__local=local=request偏函數
        object.__setattr__(self, "__name__", name)
        if callable(local) and not hasattr(local, "__release_local__"):
            object.__setattr__(self, "__wrapped__", local)        
        
      
    def __getattr__(self, name):   ##request.method執行的就是這
        if name == "__members__":
            return dir(self._get_current_object())
        return getattr(self._get_current_object(), name)  #從request對象中取出 name ,name=method
        
        
    def _get_current_object(self):
        if not hasattr(self.__local, "__release_local__"):
            return self.__local()  ##request偏函數的執行,傳回的是request對象
        try:
            return getattr(self.__local, self.__name__)
        except AttributeError:
            raise RuntimeError("no object bound to %s" % self.__name__)
      
        

def _lookup_req_object(name):  #name==request
    top = _request_ctx_stack.top   #top==ctx  ctx = requestcontext對象  此對象中有 request/session 
    if top is None:
        raise RuntimeError(_request_ctx_err_msg)
    return getattr(top, name)      #傳回的是request對象  ,top是ctx name是request
    
    @property
    def top(self):
        try:
            return self._local.stack[-1]   ##
        except (AttributeError, IndexError):
            return None
    

"""


"""  上文源碼 
    def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):   # self==app==Flask
        from werkzeug.serving import run_simple
        try:
            run_simple(host, port, self, **options)  #相當于執行self() 也就是 Flask.__call__()    # self==app==Flask
            Flask.__call__()

                def __call__(self, environ, start_response):  #environ==request
                    return self.wsgi_app(environ, start_response)

                        def wsgi_app(self, environ, start_response):
                            ctx = self.request_context(environ)  # self==app==Flask
                        ##  ctx = requestcontext對象  此對象中有 request/session  ##
                            error = None
                            try:
                                try:
                                    ctx.push()###   ctx執行的push
                                    response = self.full_dispatch_request()
                                except Exception as e:
                                    error = e
                                    response = self.handle_exception(e)
                                except:  # noqa: B001
                                    error = sys.exc_info()[1]
                                    raise
                                return response(environ, start_response)
                            finally:
                                if self.should_ignore_error(error):
                                    error = None
                                ctx.auto_pop(error)



                            def push(self):  ##self==ctx

                                top = _request_ctx_stack.top    ###_request_ctx_stack == LocalStack()=={"__storage__":{},"__ident_func__":get_ident}
                                if top is not None and top.preserved:
                                    top.pop(top._preserved_exc)

                                app_ctx = _app_ctx_stack.top
                                if app_ctx is None or app_ctx.app != self.app:
                                    app_ctx = self.app.app_context()
                                    app_ctx.push()
                                    self._implicit_app_ctx_stack.append(app_ctx)
                                else:
                                    self._implicit_app_ctx_stack.append(None)

                                if hasattr(sys, "exc_clear"):
                                    sys.exc_clear()

                                _request_ctx_stack.push(self)######### self==ctx    ctx = requestcontext對象  此對象中有 request/session

                                ###{"__storage__":{3721:{"stack":[ctx] }},"__ident_func__":get_ident}### 上文



                                def push(self, obj):   #########  obj就是ctx    self==_request_ctx_stack == LocalStack()=={"__storage__":{},"__ident_func__":get_ident}
                                    
                                    rv = getattr(self._local, "stack", None)  ##此時 self._local=={"__storage__":{},"__ident_func__":get_ident}
                                    if rv is None:
                                        self._local.stack = rv = [] ##此時 self.local=={"__storage__":{3721:{"stack":rv=[] }},"__ident_func__":get_ident}                                   
                                    rv.append(obj)  ##obj==ctx  ctx = requestcontext對象  此對象中有 request/session 此時  {"__storage__":{3721:{"stack":[ctx] }},"__ident_func__":get_ident}

                                    return rv  ##rv==ctx

                                
                                
                                class Local(object):
                                            def __setattr__(self, name, value):
                                                ident = self.__ident_func__()
                                                storage = self.__storage__
                                                try:
                                                    storage[ident][name] = value
                                                except KeyError:
                                                    storage[ident] = {name: value}
                                
                                

                                class LocalStack(object):

                                    def __init__(self):
                                        self._local = Local()

                                class Local(object):
                                    __slots__ = ("__storage__", "__ident_func__")

                                    def __init__(self):
                                        object.__setattr__(self, "__storage__", {})
                                        object.__setattr__(self, "__ident_func__", get_ident)


                        def request_context(self, environ):
                            return RequestContext(self, environ)   # self==app==Flask

                        class RequestContext(object):
                            def __init__(self, app, environ, request=None, session=None):  #self==requestcontext對象   app==app==flask
                                self.app = app
                                if request is None:
                                    request = app.request_class(environ)      #request_class = Request
                                self.request = request #######
                                self.url_adapter = None
                                try:
                                    self.url_adapter = app.create_url_adapter(self.request)
                                except HTTPException as e:
                                    self.request.routing_exception = e
                                self.flashes = None
                                self.session = session

                        class Request(RequestBase, JSONMixin):
                            pass

                        class BaseRequest(object):
                            def __init__(self, environ, populate_request=True, shallow=False):
                                self.environ = environ
                                if populate_request and not shallow:
                                    self.environ["werkzeug.request"] = self
                                self.shallow = shallow

"""      

View Code

Flask-SQLAlchemy

Flask-Script

Flask-Migrate

轉載于:https://www.cnblogs.com/bubu99/p/11229544.html