Knowledge Review
1. What is the difference between Django and flask?
The biggest difference is that the Django request is related to the data, passed through the parameters one by one, and flask is put in a place, and then to fetch, this thing called context management
2. What is WSGI?
Web Services Gateway Interface, WSGI is a protocol and specification that implements the module of the protocol:
-wsgiref
-werkzeug
The module that implements its protocol is essentially the socket server for receiving user requests and processing,
The general web framework is based on the WSGI implementation, which enables separation of concerns (popular business-related, hand-to-frame)
fromWerkzeug.wrappersImportResponse fromWerkzeug.servingImportRun_simpledefRun_sever (environ,start_response): Response=response ('Duoduo')#Wrap it up. returnresponse (Environ,start_response)if __name__=='__main__': Run_simple ('127.0.0.1', 8000,run_sever)
3, Flask provides the function
Configuration file
All configuration files are in the Flask object. config
Flask object. Config.from_object (' Path to class ') lowercase is also in effect
Application: importlib, GetAttr
Django Middleware
Rest Framework Global Configuration
Session
Placed in a cookie in the user's browser after encryption
Process:
Request arrival--------View function---------end of request
Configuration file Lifecycle 31-Day encryption settings
Routing
Adorner with parameters, custom adorner drop face
Common Url,methods,endpoint Reverse Url_for
View
FBV
Special Decorative Device
Before_first_request
Before_request
After_request
Template_global ()
Template_filter ()
ErrorHandler (404)
Requests and responses
Requests: Request
Response: Four strings, render_template (template), redirect, Jsonify (serialized)
Plus the response head is make_response.
I. Routing and views
fromFlaskImportFlaskduo=flask (__name__) @duo. Route ('/index')defindex ():Print('Index') return 'Index'if __name__=='__main__': Duo.run ()
Let's take a look at the source code of the route today:
Without looking at the middle, the discovery definition phase just returns the name of the function decorator.
1. Restrictive decorator=duo.route ('/index ')
2, @decorator This is the same as the principle of the adorner, the implementation of the name of the decorated function will be passed in
3, the F is the index function, and rule is ('/index ')
Here we can see that this decorator is essentially:
Duo.add_url_rule ('/index ', None, index)
We commented out the adorner, and ran with this code, the script ran no problem!
Let's keep looking. Add_url_rule inside the source code:
Verified what I said before. Endpoint default equals function name
Get the parameters to be placed in a similar class, click to open a look
Sure is a class
Add a path relationship to all routing relationship mapping tables
Summarize:
Try not to let endpoint duplicate name, if the same name function must be the same
Parameters:
rule, url rule view_func, view function name Defaults=none, default value, when a parameter is not in the URL, the function requires Use defaults={' k ': ' V ' for the function to provide the parameter endpoint=none, name, used to reverse generate the URL, namely: Url_for (' name ') Methods=none, the allowed request way, such as: [ "GET", "POST"]strict_slashes=none, whether the final URL/symbol is strict, @app. Route ('/index ', strict_slashes =false), access to http://www.xx.com/index/or http://www.xx.com/index can be @ap P.route ('/index ', strict_slashes=true) access only Http://www.xx.com/index Redirect_to=none, heavy Directed to the specified address @app. Route ('/index/<int:nid> ', redirect_to= '/home/<nid> ') or def func (adapter, nid): Return "/home/888" @app. Route ('/index/<int:nid> ', Redirect_to=func) Subdomain=none, sub-domain access
CBV:
fromFlaskImportflask,viewsImportFunctoolsdefWrapper (func): @functools. Wraps (func)defInner (*args,**Kwargs):returnFunc (*args,**Kwargs)returnInnerduo=flask (__name__)classUserview (views. Methodview): Methods= ['GET']#allow only get requestsdecorators = [Wrapper,]#plus the name of the adorner to be executed. defGet (self,*args,**Kwargs):return 'GET' defPost (self,*args,**Kwargs):return 'POST'Duo.add_url_rule ('/user', None,userview.as_view ('uuuu'))if __name__=='__main__': Duo.run ()
Basically similar.
Custom Regular:
fromFlaskImportFlask,url_forduo=flask (__name__)#Step One: Custom Classes fromWerkzeug.routingImportBaseconverterclassRegexconverter (baseconverter):'''custom URL-matching regular expressions''' def __init__(Self,map,regex): Super (regexconverter,self).__init__(map) Self.regex=RegexdefTo_python (self, value):'''when a route matches, the match succeeds in passing to the value of the parameter in the View function:p Aram value:: Return:''' returnint (value)defTo_url (self, value):'''when you use url_for to reverse-generate a URL, the passed parameter is processed by the method, and the return value is used to generate the parameter in the URL:p Aram value:: Return:'''Val=Super (Regexconverter,self). To_url (value)returnVal#It's completely non-writable .#Step Two: Add to converterduo.url_map.converters['Reg']=Regexconverter'''1, the user sends the request 2, the flask internally carries on the regular match 3, calls To_python (the regular Match result) Method 4, the To_python return value will give the view function the parameter'''#Step Three: Use the custom regular@duo. Route ('/index/<reg ("\d+"):nid>')defIndex (NID):Print(Nid,type (NID))Print(Url_for ('Index', nid=1)) return 'Index'if __name__=='__main__': Duo.run ()
Second, the session realization principle (source code)
Flask
Let's do a line to verify the above conjecture:
Self is the Flask object Duo,environ request related raw data
Third, blueprint
Goal: Provide a directory structure to the developer
1, first create a folder with the same name as the project, in the folder __init__.py, first define a function to create the object
from Import Flask def Create_app (): duo=flask (__name__) return duo
2, under the folder of the same name, create the View folder, create the function view of the requirement separately.
from Import BLUEPRINTUC=blueprint ('ac',__name__) @uc. Route (' /index/ ' )def index (): return'index'
3. Establish the relationship between them, import the generated object in __init__ UC, and finally register it in
from Import Flask from Import UC def Create_app (): duo=flask (__name__) duo.register_blueprint (uc,url_prefix= '/ Duoduuo ') #url_prefix适用版本控制 return duo# and finally write a script that runs,
Other Features:
Custom templates, static files
Add a prefix to a category of URLs
Add Before_request to a category of URLs
Iv. threading.local (no relationship with flask)
Let's look at a simple example:
Import Threading Import Timev=0def Task (i): Global v v=I Time.sleep (1) print(v) for in range: T=threading. Thread (target=task,args=(i,)) T.start ()# result is 9, last modification overrides all, workaround lock
See a solution:
import threading from threading local Span style= "color: #008000;" ># import timeobj =local () def Task (i): Obj.duo =i time.sleep ( 1) print (Obj.duo,i) for i in range (10 =threading. Thread (Target=task,args= (i)) T.start ()
Now let's consider a few questions,
How do I get a unique token for a thread?
Threading.get_ident () # similar to Linux process PID
Customize a function that is similar to threading.local based on a dictionary?
Build the enhanced threading.local function with Getattr,setattr!
Import TimeImportThreadingTry: ImportGreenlet#There is the process, there is no threadGet_ident=greenlet.getcurrentexceptException as E:get_ident=threading.get_identclassLocal (object): DIC={} def __getattr__(Self, item):#self.xxx triggering execution #print (' GetAttr ', item)Ident=get_ident ()ifIdentinchSelf . DIC:returnSelf . Dic[ident].get (item)returnNonedef __setattr__(Self, key, value):#self.xxx=123 triggering execution #print (' SetAttr ', Key,value)Ident=get_ident ()ifIdentinchSelf . Dic:self. Dic[ident][key]=valueElse: Self. Dic[ident]={key:value}obj=Local ()defTask (i): Obj.duo=I time.sleep (1) Print(obj.duo,i) forIinchRange (10): T=threading. Thread (target=task,args=(i,)) T.start ()
Follow up or have a look at the source of the blog:
V. Brief description of context management
1, when the request arrives, in the source code Wsgi_app the CTX object is the RequestContext encapsulates all objects and the request related raw data,
This object has the request and session, which will be supplemented in the next session to place the CTX object containing the request/session in the ' magical place '
This magical place is a large dictionary, with a thread or a unique identifier of the process as key,
2. When the view function is used:
If we take a request.method, we first import the From Flask Import request, take the CTX object according to the current thread, then fetch the request, then fetch. method
3. When the request is over:
Removes data from the ' magical place ' based on the unique tag of the current thread