Before request and after request in Flask

Keywords: Python Session Django

Catalog

If one day the business requirements of the company need to add functions to all view functions, it can be realized through decorators, but there are too many view functions, is there a better way?

Before request and after request are very simple. The functions in the implementation are the same as those of the middleware process request and process response in Django

1. Premise, disadvantages of decorator

Now we have a Flask program, which has three routing and view functions, as follows:

from flask import Flask

app = Flask(__name__)  # type:Flask


@app.route("/login")
def login():
    return "Login"

@app.route("/index")
def index():
    return "Index"

@app.route("/home")
def home():
    return "Login"

app.run("0.0.0.0", 5000)
from flask import Flask

app = Flask(__name__)  # type:Flask


@app.route("/login")
def login():
    return "Login"

@app.route("/index")
def index():
    return "Index"

@app.route("/home")
def home():
    return "Login"

app.run("0.0.0.0", 5000)

If you log in, you can visit the index and home pages. If you don't log in, you can jump to login

How to solve this problem? Session pair. Use all functions except Login function of session to check whether session is logged in

It's too much trouble. Now we only have three functions. If there are hundreds of functions, how can they be integrated

Decorator, yes, decorator is a good solution, but ah, I still have thousands of functions. It's still troublesome for me to add @ decorator to every function definition

2. Before & after request

2.1 before Ou request analysis:

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/home")
def home():
    return "Hello"

@app.before_request
def be1():
    print("be1")
    return "Error"
    # return None

@app.before_request
def be2():
    print("be2")
    return None

@app.after_request
def af1(res):
    print("af1")
    return res

@app.after_request
def af2(res):
    print("af2")
    return res


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

Error message:

#In Django, if the request directly fails to meet the conditions to return when it reaches request 1, that is, return HttpResponse("Md1 interrupt"), the program will send the request directly to middleware 1 to return, and then return to the requester in turn, and no longer execute the view function
 #In Flask, if the request directly fails to meet the conditions when it reaches request 1, it will return to the requester in turn in the last @ app.after \
Return to the page interrupted by Md2, and print in the background as follows:
be1
af2
af1

2.2 after request analysis:

@If the app.after'request reports an error, the results will be returned in turn

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/home")
def home():
    return "Hello"

@app.before_request
def be1():
    print("be1")
    # return "there is an error."
    return None

@app.before_request
def be2():
    print("be2")
    return None

@app.after_request
def af1(res):
    print("af1")
    return res

@app.after_request
def af2(res):
    print("af2")
    # return res
    return "Error"

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

Error message:

# Return result be1
be2
af2
af1

3. Before you request application

@App.before-u request is executed before the request enters the view function

@App.before'u request is also a decorator. All functions decorated by it will be executed before the request enters the view function

request.path is to read the current url address. If it is / login, it is allowed to directly pass return None, which can be understood as pass

Verify whether there is user in the session. If not, it indicates that there is no login. Therefore, the merciless redirect("/login") will jump to the login page

There is another @app.before_first_request to be mentioned, which is very similar to or similar to @app.before_request, but it will only be executed once.

from flask import Flask
from flask import request
from flask import redirect
from flask import session

app = Flask(__name__)  # type:Flask
app.secret_key = "DragonFire"

@app.before_request
def is_login():   #White list
    if request.path == "/login":
        return None
   #Verify session
    if not session.get("user"):
        return redirect("/login")  return None

@app.route("/login")
def login():
    return "Login"

@app.route("/index")
def index():
    return "Index"

@app.route("/home")
def home():
    return "Login"

app.run("0.0.0.0", 5000)

4. Before you request application

@App.after'request is executed before the response is returned to the client, and after the view function is ended

@App.after'request must return the parameter environ of the previous layer, otherwise an error will be reported

@app.after_request
def foot_log(environ):
    if request.path != "/login":
        print("There's a visitor",request.path)
    return environ

5. Implement a simple page login with flash

Authentication login based on before request and after request

from flask import Flask,render_template,request,redirect,session
app = Flask(__name__,template_folder='templates')
app.secret_key = "sdsfdsgdfgdfgfh"

@app.before_request
def process_request():
    if request.path=="/login":
        return None
    if not session.get("user_info"):
        return redirect("/login")
    return None
@app.after_request
def process_response(response):
    print(2222)
    return response

@app.route("/login",methods=["GET","POST"])
def login():
    if request.method=="GET":
        return render_template("login.html")
    else:
        # print(request.values)   #There's everything in this. It's like a body
        username = request.form.get("username")
        password = request.form.get("password")
        if username=="annie" and password=="123":
            session["user_info"] = username
            # session.pop("user_info")  #Delete session
            return redirect("/index")
        else:
            # return render_template("login.html",**{"msg": "wrong user name or password"})
            return render_template("login.html",msg="Wrong user name or password")


@app.route("/index",methods=["GET","POST"])
def index():
    # if not session.get("user_info"):
    #     return redirect("/login")
    return render_template("index.html")


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

Posted by yarub on Fri, 22 Nov 2019 04:43:50 -0800