《Flask Web开发实战:入门、进阶与原理解析》-李辉 笔记代码学习和注释(第一章-初识Flask 和 第二章-Flask与HTTP)

《Flask Web开发实战:入门、进阶与原理解析》-李辉 笔记代码学习和注释(第一章-初识Flask 和 第二章-Flask与HTTP),第1张

《Flask Web开发实战:入门、进阶与原理解析》-李辉 笔记代码学习和注释(第一章-初识Flask 和 第二章-Flask与HTTP) 一、前言

学习这本书,然后自己对其中的代码加了一些注释,便于学习和理解。
代码可以在https://github.com/greyli/helloflask/下载到

二、C/S和B/S

先看两张书上的图:
第一张图是C/S架构的图,C(Client,用户),S(Server,服务器)
第二张是Flask Web的工作流程
客户端先通过http,用URL向服务器端发送请求,然后服务器端通过一个约定好的叫做WSGI的标准,与Flask程序交互,返回Flask处理好的东西,然后再通过Web服务器传回客户端浏览器。

三、MVC和MTV框架模式

MVC是一种常用的框架模式,MTV是Flask所用的框架模式,但是二者相差不大。

  1. MVC的V(view)对应的是MTV的T(template),二者都起视图展示的作用,只是叫法不同,在Flask中,template主要由待渲染的HTML文件组成。
  2. MVC的C(control)对应的是MTV的V(view),这里要注意的是,这个view是视图函数,其实它起一个控制器的作用,视图函数的意思就是用来控制视图的函数。
  3. MVC和MTV的M指的是模型,用来处理程序需要 *** 作的数据,先按下不表,以后再提到。

四、代码及注释
import os
try:
    from urlparse import urlparse, urljoin
except importError:
    from urllib.parse import urlparse, urljoin

from jinja2 import escape
from jinja2.utils import generate_lorem_ipsum
from flask import Flask, make_response, request, redirect, url_for, abort, session, jsonify

app = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY', 'secret string')#这个和cookie还有session有关,用来设置session秘钥


# get name value from query string and cookie #从query string和cookie中,查询name变量
#query string指的是查询字符串,详见P29,比如URL:http://helloflask.com/hello?name=Grey,其中的?name=Grey

@app.route('/')#一般来讲必须有主页的视图,不然容易报错,这里是让/主页和/'hello',共用了一个视图函数,会返回相同的效果。
@app.route('/hello')
def hello():
    name = request.args.get('name')#args从url的query中找到name后面的键值,这里不能用cookies,因为还没生成对应的cookies
    if name is None:#记得判断如果为空,则默认为human
        name = request.cookies.get('name', 'Human')#第一个参数是self key,即键,就设置为name就行了,# 第二个参数是default值,get函数既有返回值,又能进行赋值处理
    #如果后面生成了cookie的话,这里可以用cookies(下面那个set_cookie视图函数可以生成cookie
    response = 'Hello, %s!' % escape(name)  # escape name to avoid XSS
    # return different response according to the user's authentication status
    # 根据用户的身份验证状态返回不同的响应
    if 'logged_in' in session:
        response += '[Authenticated]'
    else:
        response += '[Not Authenticated]'
    return response


# redirect
@app.route('/hi')#重定向,把hi定向到hello里面
def hi():
    return redirect(url_for('hello'))


# use int URL converter
#可以在url里面设置变量,含义为,在year前面加一个int转换器,这样它就从url变成了一个int变量,在视图函数中可以直接调用这个变量
@app.route('/goback/')
def go_back(year):
    return 'Welcome to %d!' % (2021 - year)

# use any URL converter
@app.route('/colors/')#变量的另一个例子,相当于是用了个any向量(行)
def three_colors(color):
    return '

Love is patient and kind. Love is not jealous or boastful or proud or rude.

' # return error response @app.route('/brew/')#未指定类型的变量 def teapot(drink): if drink == 'coffee': abort(418) else: return 'A drop of tea.' # 404 @app.route('/404') def not_found(): abort(404) # return response with different formats #不同格式的响应 @app.route('/note', defaults={'content_type': 'text'})#content_type和query_string之类的一样,都是url里面的东西,这里用defaults在调用这个参数的时候给它赋一个默认的值 @app.route('/note/')#如果输入的不是默认值的话,比如note/html,则显示出来HTML格式的 def note(content_type):#python的三个单引号表示直接输出 content_type = content_type.lower()#这里注意细节,用lower()函数将其转化为小写,因为windows和mac os的url是不区分大小写的,但是linux和unix的路径部分是区分的 if content_type == 'text': body = '''Note to: Peter from: Jane heading: Reminder body: Don't forget the party! ''' #make_response用来设置响应,并标记其响应头,比如content-type就是响应头中的一个,可以在网页中用f12测试一下 response = make_response(body)#用make_response函数生成响应对象 #make_response的返回的response的常用方法和属性在P47 response.mimetype = 'text/plain'#text/plain代表纯文本格式 elif content_type == 'html': body = ''' Note

to: Peter

from: Jane

heading: Reminder

body: Don't forget the party!

''' response = make_response(body) response.mimetype = 'text/html' elif content_type == 'xml': body = ''' Peter Jane Reminder Don't forget the party! ''' response = make_response(body) response.mimetype = 'application/xml' elif content_type == 'json': body = {"note": { "to": "Peter", "from": "Jane", "heading": "Remider", "body": "Don't forget the party!" } } response = jsonify(body) # equal to: # response = make_response(json.dumps(body)) # response.mimetype = "application/json" else: abort(400) return response # set cookie @app.route('/set/')#定义了一个变量,用来设置cookie def set_cookie(name): response = make_response(redirect(url_for('hello'))) #调用response的用来set_cookie的方法,将变量name传到名为name的cookie里,打开浏览器f12就能看的 response.set_cookie('name', name) return response #处理登录问题要注意加密,要用session而不是cookie # log in user @app.route('/login') def login(): session['logged_in'] = True #这个session相当于一个字典,这里直接自定义一个名为'logged_in'的东西(根据习惯命名即可),让它作为键,然后值是一个布尔类型 return redirect(url_for('hello')) #这里是根据开发时具体的情况而定,一般会在登录后返回登录前处在的界面,这里是返回了主页 # protect view @app.route('/admin') def admin(): if 'logged_in' not in session:#用了一个字典的查询 *** 作 abort(403) return 'Welcome to admin page.'#后面具体开发的时候,要填上对应的模板和表单 # log out user @app.route('/logout') def logout(): if 'logged_in' in session: session.pop('logged_in')#字典的pop *** 作,其实字典里面是一个平衡树 return redirect(url_for('hello')) # AJAX @app.route('/post') def show_post(): post_body = generate_lorem_ipsum(n=2) return ''' A very long post %s ''' % post_body @app.route('/more') def load_post(): return generate_lorem_ipsum(n=1) # redirect to last page @app.route('/foo') def foo(): return 'Foo pageDo something and redirect' % url_for('do_something', next=request.full_path) @app.route('/bar') def bar(): return 'Bar pageDo something and redirect' % url_for('do_something', next=request.full_path)#这里是一个函数嵌套的情况 #最外面是url_for,给其中加了一个名为next的参数,这就相当于是一个外层的变量,里面存的是当前页面的完整路径 #然后执行return函数,跳转到了do-something,实际开发中应该会跳转到某个新的页面,就放在这一层里,然后处理完之后,在do-something里面调用了redirect_back #然后又执行redirect_back,因为内层函数可以调用外层的变量,所以在这一层还是可以调用next变量 @app.route('/do-something') def do_something(): # do something here return redirect_back() #依然要注意安全问题,防止开放重定向漏洞 def is_safe_url(target): ref_url = urlparse(request.host_url) test_url = urlparse(urljoin(request.host_url, target)) return test_url.scheme in ('http', 'https') and ref_url.netloc == test_url.netloc def redirect_back(default='hello', **kwargs): for target in request.args.get('next'), request.referrer:#这里相当于用for循环尝试两种可能,target相当于平时的i变量 if not target: continue if is_safe_url(target): return redirect(target) return redirect(url_for(default, **kwargs))

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/3973721.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-10-21
下一篇 2022-10-21

发表评论

登录后才能评论

评论列表(0条)

保存