1. 运用Flask进行Web开发

1.1 运用虚拟环境

运用虚拟环境是一种杰出的做法,能够将项目的依靠项阻隔在一个独立的环境中,以防止与其他项目的依靠项抵触。以下是在虚拟环境中操作的进程:

进程1:创立虚拟环境

首要,您需求创立一个虚拟环境。在指令行中导航到您期望创立虚拟环境的目录,然后运转以下指令:

python -m venv myenv

这将在当时目录下创立一个名为myenv的虚拟环境。您能够将myenv替换为您喜爱的称号。

进程2:激活虚拟环境

在Windows上,在指令提示符中运转以下指令:

myenv\Scripts\activate

在 macOS 和 Linux 上,在终端中运转以下指令:

source my
1.2 装置Flask

进程1:装置Flask

首要,保证您现已装置了Python。然后,您能够运用pip装置Flask:

pip install Flask

进程2:创立一个根本的Flask运用

创立一个新的文件,例如app.py,并在其间编写以下代码:

from flask import Flask
​
app = Flask(__name__)
​
@app.route('/')
def hello_world():
   return 'Hello, World!'if __name__ == '__main__':
   app.run()

这个简略的运用界说了一个根路由(’/’),当拜访根URL时,它将回来”Hello, World!”。

进程3:运转Flask运用

在指令行中,进入包含app.py的目录,并运转运用:

python app.py

您将看到Flask运用发动,并在终端上显现输出。拜访http://localhost:5000/,您应该能够在浏览器中看到”Hello, World!”。

进程4:创立更多的路由和视图

您能够创立更多的路由和视图函数,以构建更杂乱的Web运用。例如:

@app.route('/about')
def about():
   return 'This is the About page.'@app.route('/contact')
def contact():
   return 'Contact us at contact@example.com'

进程5:运用模板

Flask支撑运用模板引擎来烘托动态HTML页面。您能够运用Jinja2模板引擎或其他模板引擎。首要,需求创立一个名为”templates”的文件夹,然后在运用中装备模板引擎:

from flask import Flask, render_template
​
app = Flask(__name__)
​
@app.route('/')
def index():
   return render_template('index.html')

进程6:处理表单和用户输入

Web运用一般需求处理用户输入,例如表单。您能够运用Flask-WTF等扩展来处理表单验证和处理。

这仅仅Flask的入门,您能够持续学习Flask的其他功用,如数据库集成、用户认证、API开发等。Flask有丰厚的文档和社区支撑,这将有助于您深化了解Web开发。

请注意,Web开发是一个广泛的范畴,您或许需求学习HTML、CSS、JavaScript等前端技术以及数据库操作等后端技术,以构建完好的Web运用程序。期望这个简略的入门指南对您有所协助,祝您学习愉快!

1.3 具体操作

在PyCharm中创立Python程序并运用虚拟环境十分简略。以下是一个简略的进程,我会供给必要的截图来协助您:

进程1:翻开PyCharm

首要,翻开PyCharm集成开发环境。

进程2:创立新项目

点击菜单中的”File”,然后挑选”New Project”。

进程3:装备虚拟环境

在新项目设置窗口中,挑选您的项目方位,然后在”Interpreter”部分点击右侧的”…”按钮。

进程4:创立新虚拟环境

在翻开的窗口中,点击右上角的”+ Create VirtualEnv”。

进程5:命名虚拟环境

进程6:创立新项目

进程7:创立Python文件

进程8:编写Python代码

现在,您能够在新的Python文件中编写Python代码了。

进程9:运转Python程序

在修改器中,右键单击Python文件,然后挑选”Run ‘your_file_name'”来运转程序。

这就是在PyCharm中创立Python程序并运用虚拟环境的根本进程。请注意,您需求保证您现已装置了PyCharm,而且现已为项目装备了虚拟环境。假如您的PyCharm版本有所不同,界面或许会有少许改变,但根本进程是类似的。期望这些截图和进程能协助您开端在PyCharm中进行Python开发。

1.4 路由

Flask的路由体系答应您界说URL与视图函数之间的映射联系。路由决议了当拜访特定URL时,应该调用哪个视图函数来处理恳求。以下是Flask路由的具体解说:

根本路由示例:

from flask import Flask
​
app = Flask(__name__)
​
@app.route('/')
def index():
   return 'Hello, World!'

在上面的示例中,@app.route('/') 是一个装修器,它告知Flask当用户拜访根URL(’/’)时,应该调用 index 函数来处理恳求。index 函数回来一个简略的“Hello, World!”音讯。

变量规矩:

您能够在路由中包含变量部分,这些变量部分会捕获URL中的值,并将它们作为参数传递给视图函数。

@app.route('/user/<username>')
def show_user_profile(username):
   return 'User Profile: {}'.format(username)

在上面的示例中,` 是一个变量规矩,它会捕获URL中的任何文本,并将其传递给show_user_profile` 函数。

路由参数类型约束:

您还能够约束路由参数的类型,例如整数或浮点数:

@app.route('/post/<int:post_id>')
def show_post(post_id):
   return 'Post ID: {}'.format(post_id)

这个路由只会匹配整数类型的 post_id 参数。

多个路由:

您能够为一个视图函数界说多个路由,以便多个URL都能够映射到同一个视图函数:

@app.route('/')
@app.route('/home')
def home():
   return 'Home Page'

上面的路由装备答运用户拜访根URL(’/’)或’/home’,都会调用 home 函数。

HTTP办法:

路由默许运用GET办法,但您能够运用 methods 参数来指定其他HTTP办法,例如POST、PUT等:

@app.route('/submit', methods=['POST'])
def submit():
   return 'Form Submitted'

这个路由只会匹配POST恳求。

URL构建:

Flask还供给了 url_for 函数,用于在运用中构建URL。这能够协助您防止硬编码URL,并使代码更具可保护性。

from flask import url_for
​
@app.route('/profile')
def profile():
   # 构建URL,依据视图函数名字(这儿是index)
   url = url_for('index')
   return 'URL for index: {}'.format(url)

这仅仅Flask路由的根底,您还能够运用更高档的路由功用,例如蓝图(Blueprints)来安排运用程序的路由,以及URL重定向、过错处理等功用来构建强壮的Web运用程序。路由是构建Web运用程序的要害组成部分之一,答应您界说URL和视图之间的映射联系。

1.5 转换器

Flask供给了一些自带的URL参数转换器,用于捕获和处理特定类型的参数值。这些转换器答应您在路由中指定参数的类型或格局,并能够经过视图函数的参数传递。

以下是Flask自带的一些常用URL参数转换器:

  1. int 捕获整数参数。

    @app.route('/user/<int:user_id>')
    def show_user(user_id):
       return 'User ID: {}'.format(user_id)
    
  2. float 捕获浮点数参数。

    @app.route('/price/<float:product_price>')
    def show_product_price(product_price):
       return 'Product Price: {}'.format(product_price)
    
  3. path 捕获包含斜杠的途径参数,一般用于捕获整个URL段。

    @app.route('/path/<path:subpath>')
    def show_subpath(subpath):
       return 'Subpath: {}'.format(subpath)
    
  4. string 捕获字符串参数(默许转换器,能够省掉)。

    @app.route('/user/<string:username>')
    def show_username(username):
       return 'Username: {}'.format(username)
    
  5. uuid 捕获UUID格局的参数。

    @app.route('/resource/<uuid:resource_id>')
    def show_resource(resource_id):
       return 'Resource ID: {}'.format(resource_id)
    

这些转换器答应您界说路由中的参数类型,而且会主动验证和转换传递的参数值。假如参数值与转换器不匹配,Flask将回来404过错。

您还能够自界说URL参数转换器,以满意特定的运用需求,但上述自带的转换器一般能够满意大多数状况。运用这些转换器,您能够更精确地界说路由,捕获特定类型的参数,并经过视图函数的参数进行拜访和处理。

自界说转化器

在Flask中,您能够自界说URL参数转换器,以满意特定的运用需求。自界说转换器答应您界说自己的参数验证和转换逻辑。以下是自界说转换器的根本进程:

  1. 创立自界说转换器类,该类需求承继自werkzeug.routing.BaseConverter
  2. 完结to_python 办法,用于将URL参数转换为Python方针。
  3. 完结to_url 办法,用于将Python方针转换为URL参数。
  4. 在Flask运用中注册自界说转换器。

以下是一个示例,演示怎么创立自界说转换器来匹配年份(四位整数):

from flask import Flask
from werkzeug.routing import BaseConverter
​
app = Flask(__name__)
​
# 创立自界说转换器类
class YearConverter(BaseConverter):
   def to_python(self, value):
     try:
       year = int(value)
       if 1000 <= year <= 9999:
         return year
     except ValueError:
       pass
     raise ValueError('Invalid year format')
​
   def to_url(self, value):
     return str(value)
​
# 在Flask运用中注册自界说转换器
app.url_map.converters['year'] = YearConverter
​
# 运用自界说转换器
@app.route('/year/<year:year>')
def show_year(year):
   return 'Year: {}'.format(year)
​
if __name__ == '__main__':
   app.run()

在上面的示例中,咱们首要创立了一个名为YearConverter的自界说转换器类,它承继自BaseConverter。然后,咱们完结了to_python 办法,用于将URL参数转换为整数表明的年份,以及to_url 办法,用于将Python方针转换回URL参数。

接下来,咱们在Flask运用中注册了这个自界说转换器,运用app.url_map.converters 字典来增加转换器。最终,咱们运用自界说转换器在路由中界说了一个新的URL规矩,其间year:year 指定了参数名和转换器。

现在,当用户拜访/year/2023时,Flask将主动将2023转换为整数,并传递给show_year 视图函数。假如URL中的年份不是四位整数,自界说转换器将引发ValueError,并回来404过错。这样,您能够在Flask中自界说转换器以满意运用的特定需求。

1.6 flask的request

Flask的request方针用于获取有关HTTP恳求的信息,包含恳求头、查询参数、表单数据、文件上传等。经过request方针,您能够拜访和操作来自客户端的数据。以下是关于Flask中request方针的具体解说:

获取恳求办法(HTTP办法):

  • request.method:回来HTTP恳求的办法,例如GET、POST、PUT、DELETE等。
pythonCopy codefrom flask import request
​
@app.route('/method', methods=['GET', 'POST'])
def get_method():
   return 'Request method is {}'.format(request.method)

获取查询参数:

  • request.args:一个字典,包含来自URL查询字符串的参数。
from flask import request
​
@app.route('/query')
def get_query_param():
   param_value = request.args.get('param_name')
   return 'Query parameter value: {}'.format(param_value)

获取表单数据:

  • request.form:一个字典,包含来自HTTP POST恳求的表单数据。
from flask import request, render_template
​
@app.route('/form', methods=['POST'])
def get_form_data():
   username = request.form['username']
   password = request.form['password']
   return 'Username: {}, Password: {}'.format(username, password)

获取JSON数据:

  • request.get_json():从HTTP恳求的主体中获取JSON数据。
pythonCopy codefrom flask import request
​
@app.route('/json', methods=['POST'])
def get_json_data():
   data = request.get_json()
   return 'Received JSON data: {}'.format(data)

获取文件上传:

  • request.files:一个字典,包含来自HTTP POST恳求的文件上传。
from flask import request
​
@app.route('/upload', methods=['POST'])
def upload_file():
   file = request.files['file']
   # 处理上传的文件,保存到服务器或进行其他操作
   return 'Received file: {}'.format(file.filename)

获取恳求头:

  • request.headers:一个字典,包含HTTP恳求的一切恳求头。
from flask import request
​
@app.route('/headers')
def get_headers():
   user_agent = request.headers.get('User-Agent')
   return 'User-Agent: {}'.format(user_agent)

获取Cookie:

  • request.cookies:一个字典,包含HTTP恳求中的一切Cookie。
from flask import request
​
@app.route('/cookie')
def get_cookie():
   cookie_value = request.cookies.get('cookie_name')
   return 'Cookie value: {}'.format(cookie_value)

Flask的request方针供给了许多办法和特色,用于拜访和操作HTTP恳求中的数据。依据恳求类型和运用的需求,您能够运用request方针来获取查询参数、表单数据、JSON数据、文件上传、恳求头、Cookie等信息。这使得处理各种类型的HTTP恳求变得十分灵敏和便利。

1.7 静态文件

在Flask中,您能够运用静态文件夹来存储和供给静态资源(如CSS、JavaScript、图画等)。Flask会主动将位于静态文件夹中的文件映射到运用程序的URL途径上,以便拜访这些静态资源。

以下是怎么在Flask中设置和拜访静态资源的进程:

  1. 创立静态文件夹: 在您的Flask项目根目录下,创立一个名为static的文件夹。这将是寄存静态资源的文件夹。

    /your_project_folder
    ├── app.py
    ├── static/
    │  ├── css/
    │  │  └── style.css
    │  ├── js/
    │  │  └── script.js
    │  └── images/
    │    └── logo.png
    └── templates/
    
  2. 拜访静态资源: Flask会主动将/static/途径映射到静态文件夹。您能够运用url_for() 函数来构建静态资源的URL:

    from flask import Flask, render_template, url_for
    ​
    app = Flask(__name__)
    ​
    @app.route('/')
    def index():
       return render_template('index.html')
    ​
    if __name__ == '__main__':
       app.run()
    

    在模板中,您能够运用url_for()来获取静态资源的URL,例如:

    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
    <script src="{{ url_for('static', filename='js/script.js') }}"></script>
    <img src="{{ url_for('static', filename='images/logo.png') }}" alt="Logo">
    

    上述代码将会生成相应静态资源的URL,例如/static/css/style.css/static/js/script.js,和 /static/images/logo.png

  3. 运转运用程序: 发动Flask运用并拜访相应的路由,即可拜访静态资源。

    http://localhost:5000/
    

经过这种办法,您能够在Flask运用中轻松拜访静态资源,而无需处理文件途径或URL构建的杂乱性。保证将静态资源存储在static文件夹中,并在模板中运用url_for()函数来生成正确的URL。这样,您能够有用地办理和供给静态资源

怎么自界说静态资源文件夹

在Flask中,您能够自界说静态资源文件夹的方位,以满意您的项目结构需求。默许状况下,Flask将静态资源文件夹设置为项目根目录下的static文件夹。要自界说静态资源文件夹的方位,您能够运用static_folder参数来指定新的文件夹途径。

以下是怎么自界说静态资源文件夹的进程:

  1. 在您的Flask运用创立时,经过传递static_folder参数来指定新的静态资源文件夹途径。例如:
from flask import Flask
​
app = Flask(__name__, static_folder='path/to/your/static/folder')

请将 'path/to/your/static/folder' 替换为您期望将静态资源存储的实践文件夹途径。

  1. 保证新的静态资源文件夹包含所需的静态资源文件,如CSS、JavaScript、图画等。
  2. 在模板中运用url_for()函数来获取静态资源的URL,如前面所述。Flask会依据您指定的static_folder参数生成相应的URL。
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
<img src="{{ url_for('static', filename='images/logo.png') }}" alt="Logo">
  1. 运转运用程序并拜访相应的路由,即可拜访自界说静态资源文件夹中的静态资源。

经过自界说静态资源文件夹的方位,您能够更灵敏地安排和办理静态资源,以习惯不同的项目结构和需求。这使得您能够更好地操控静态资源的存储和拜访。

1.8 模板文件

在Flask中,您能够运用render_template()函数将模板文件作为呼应回来给客户端。模板文件一般包含HTML和动态内容,经过烘托模板,您能够生成包含动态数据的页面,并将其发送给客户端。

以下是在Flask中回来模板文件作为呼应的具体进程:

  1. 创立模板文件夹: 在您的Flask项目根目录下,创立一个名为templates的文件夹。这将是寄存模板文件的文件夹。

    /your_project_folder
    ├── app.py
    ├── static/
    ├── templates/
    │  ├── index.html
    │  ├── other_template.html
    │  └── ...
    

    模板文件一般运用.html扩展名,但也能够运用其他模板引擎(如Jinja2)支撑的扩展名。

  2. 创立模板文件:templates文件夹中,创立您的模板文件。模板文件能够包含HTML代码和模板引擎符号,用于刺进动态数据。

    htmlCopy code<!-- templates/index.html -->
    <!DOCTYPE html>
    <html>
    <head>
       <title>Flask Template Example</title>
    </head>
    <body>
       <h1>Hello, {{ username }}!</h1>
    </body>
    </html>
    

    上面的模板文件包含一个占位符 {{ username }},该占位符将由视图函数中的动态数据替代。

  3. 在视图函数中运用render_template()函数: 在您的Flask运用中,运用render_template()函数来烘托模板并将其作为呼应回来。

    from flask import Flask, render_template
    ​
    app = Flask(__name__)
    ​
    @app.route('/')
    def index():
       username = 'John'  # 动态数据示例
       return render_template('index.html', username=username)
    

    在视图函数中,咱们运用render_template()函数来烘托index.html模板,并将动态数据 username 传递给模板。

  4. 运转运用程序: 发动Flask运用并拜访相应的路由,模板文件将被烘托并作为呼应回来给客户端。

    arduinoCopy code
    http://localhost:5000/
    

经过上述进程,您能够将模板文件作为呼应回来给客户端,而且能够动态刺进数据以生成页面内容。这使得您能够构建具有动态内容的Web运用程序。

1.9 flask呼应

在Flask中,呼应(Response)是服务器向客户端发送的HTTP呼应音讯。经过呼应,您能够操控HTTP状况码、设置呼应头、回来呼应内容等。Flask供给了丰厚的东西和函数来构建和自界说HTTP呼应。以下是有关Flask呼应的具体解说:

创立呼应方针:

在Flask中,您能够运用make_response()函数创立一个呼应方针,然后对其进行设置。

from flask import Flask, make_response
​
app = Flask(__name__)
​
@app.route('/custom_response')
def custom_response():
   response = make_response('This is a custom response', 200)
   response.headers['Content-Type'] = 'text/plain'
   return response

在上面的示例中,咱们运用make_response()函数创立了一个呼应方针,设置了呼应内容和HTTP状况码(200 OK),然后设置了呼应头的Content-Type字段。最终,咱们将呼应方针回来给客户端。

设置呼应状况码:

  • response.status_code:用于设置呼应的HTTP状况码。默许状况下,状况码为200。
response.status_code = 404

设置呼应头:

  • response.headers:一个字典,包含呼应的HTTP头信息。您能够运用该字典来设置自界说呼应头字段。
response.headers['Content-Type'] = 'application/json'

设置Cookie:

  • response.set_cookie():用于设置呼应中的Cookie。
response.set_cookie('cookie_name', 'cookie_value')

回来JSON呼应:

  • jsonify():Flask供给的函数,用于回来JSON格局的呼应。
from flask import jsonify
​
@app.route('/json_response')
def json_response():
   data = {'message': 'Hello, JSON!'}
   return jsonify(data)

回来文件呼应:

  • send_file():用于回来文件作为呼应。
from flask import send_file
​
@app.route('/download')
def download_file():
   filename = 'path/to/your/file.txt'
   return send_file(filename, as_attachment=True)

回来重定向:

  • redirect():用于履行重定向到其他URL。
from flask import redirect
​
@app.route('/redirect')
def perform_redirect():
   return redirect('/new_url')

Flask的呼应方针和相关函数使得您能够十分灵敏地构建和自界说HTTP呼应。这使得您能够依据需求设置状况码、呼应头、内容、Cookie等,以满意您的运用程序的需求。无论是回来HTML页面、JSON数据、文件下载仍是履行重定向,Flask都供给了便利的东西来处理各种类型的呼应。

flask重定向呼应

Flask中,您能够运用redirect()函数来履行重定向操作,将用户从一个URL重定向到另一个URL。重定向是在Web运用程序中常见的一种行为,用于将用户导航到不同的页面或资源。以下是怎么在Flask中创立重定向呼应的示例:

from flask import Flask, redirect, url_for
​
app = Flask(__name__)
​
# 界说一个路由,该路由将履行重定向到另一个URL
@app.route('/redirect_example')
def perform_redirect():
   # 运用 redirect() 函数将用户重定向到指定URL
   return redirect('/new_url')
​
# 界说另一个路由,该路由是重定向方针
@app.route('/new_url')
def new_url():
   return 'This is the new URL.'if __name__ == '__main__':
   app.run()

在上面的示例中,咱们首要界说了一个路由/redirect_example,当用户拜访该路由时,它履行重定向操作,将用户重定向到/new_url路由。

  • redirect('/new_url'):这行代码运用redirect()函数将用户重定向到/new_url路由。

接着,咱们界说了/new_url路由,这是重定向的方针,它回来一个简略的音讯。当用户拜访/redirect_example时,他们将被重定向到/new_url路由,并看到相应的音讯。

经过运用redirect()函数,您能够轻松地履行重定向操作,并将用户导航到其他URL。这在完结用户登录、页面切换、处理表单提交等状况下十分有用。假如需求在路由之间导航,还能够运用url_for()函数来构建URL,以保证路由的灵敏性和可保护性。

2.0 flask的状况坚持

在Web运用中,状况坚持是一种机制,用于在不同HTTP恳求之间保存或共享数据。Flask供给了多种办法来完结状况坚持,包含:

  1. Cookies: 运用HTTP Cookies能够在客户端和服务器之间存储小型数据,以便在后续恳求中拜访。Flask供给了request.cookies来拜访客户端发送的Cookie,以及response.set_cookie()来设置Cookie。

    from flask import Flask, request, make_response
    ​
    app = Flask(__name__)
    ​
    @app.route('/')
    def index():
       username = request.cookies.get('username')
       return 'Hello, {}'.format(username)
    ​
    @app.route('/set_cookie/<username>')
    def set_cookie(username):
       response = make_response('Cookie set')
       response.set_cookie('username', username)
       return response
    
  2. Session: Flask的session方针能够用来在不同恳求之间存储数据。默许状况下,Flask运用签名Cookie来存储会话数据。

    from flask import Flask, session, redirect, url_for, request
    ​
    app = Flask(__name__)
    app.secret_key = 'your_secret_key'  # 需求设置一个隐秘密钥来保护会话数据@app.route('/')
    def index():
       if 'username' in session:
         return 'Logged in as {}'.format(session['username'])
       return 'Not logged in'@app.route('/login/<username>')
    def login(username):
       session['username'] = username
       return redirect(url_for('index'))
    ​
    @app.route('/logout')
    def logout():
       session.pop('username', None)
       return redirect(url_for('index'))
    

    请注意,运用会话需求设置一个隐秘密钥,以保证会话数据的安全性。

  3. URL参数: 您能够运用URL参数来传递数据,这关于一次性或暂时传递数据很有用。例如,将数据附加到URL中并在下一个恳求中拜访它。

    from flask import Flask, request
    ​
    app = Flask(__name__)
    ​
    @app.route('/greet')
    def greet():
       name = request.args.get('name')
       return 'Hello, {}'.format(name)
    

这些是在Flask中完结状况坚持的一些常用办法。您能够依据您的运用程序需求挑选合适的办法。 Cookies 和会话一般用于在多个恳求之间坚持用户身份验证状况、存储购物车信息等用户相关数据,而URL参数一般用于传递暂时数据或特定恳求的参数

  1. jwt

    首要,请保证您现已装置了 pyjwt 库:

    pip install pyjwt
    

    然后,您能够运用以下代码创立和验证JWT令牌:

    import jwt
    import datetime
    ​
    # 密钥用于签署和验证JWT令牌,请保证保密安全
    SECRET_KEY = 'your_secret_key'# 模仿用户数据库(用户名和暗码)
    user_db = {
       'user123': 'password123'
    }
    ​
    # 创立用户登录功用
    def login(username, password):
       if username in user_db and user_db[username] == password:
         return True
       return False# 创立一个JWT令牌
    def create_jwt_token(username):
       # 设置JWT令牌的有用期为1小时
       expiration_time = datetime.datetime.utcnow() + datetime.timedelta(hours=1)
      
       payload = {
         'username': username,
         'exp': expiration_time
       }
    ​
       token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
       return token
    ​
    # 验证JWT令牌
    def verify_jwt_token(token):
       try:
         payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
         return payload
       except jwt.ExpiredSignatureError:
         return None  # 令牌已过期
       except jwt.InvalidTokenError:
         return None  # 无效的令牌# 示例用户登录和JWT令牌生成
    def main():
       username = 'user123'
       password = 'password123'if login(username, password):
         jwt_token = create_jwt_token(username)
         print('JWT Token:', jwt_token)
        
         # 模仿客户端恳求,并验证JWT令牌
         decoded_payload = verify_jwt_token(jwt_token)
         if decoded_payload:
           print('Token verified. User:', decoded_payload['username'])
         else:
           print('Token verification failed.')
    ​
    if __name__ == '__main__':
       main()
    

    在上述示例中,咱们首要界说了一个用户数据库 user_db,包含了模仿的用户名和暗码。然后,咱们创立了一个用户登录函数 login(),用于验证用户身份。接下来,咱们界说了 create_jwt_token() 函数来生成JWT令牌,并将令牌的有用期设置为1小时。最终,咱们创立了 verify_jwt_token() 函数来验证JWT令牌。

    main() 函数中,咱们模仿用户登录并生成JWT令牌。然后,咱们模仿客户端恳求,并运用 verify_jwt_token() 函数验证JWT令牌的有用性。假如令牌验证成功,将打印出用户的用户名。

    这个示例演示了怎么运用 pyjwt 库创立和验证JWT令牌,以完结用户身份验证和状况坚持功用。请注意,实践运用中,您或许需求更杂乱的用户办理和安全性措施。

    flask的反常捕获处理

    在Flask运用中,您能够运用反常捕获来处理各种过错和反常状况,以供给更友爱的过错页面或呼应音讯,一起增强运用的可靠性和安全性。以下是一些常见的反常处理和反常处理办法:

    运用@app.errorhandler装修器

    @app.errorhandler装修器能够用于捕获和处理特定HTTP过错或自界说反常。您能够将它运用于视图函数,以便在呈现特定反常时履行自界说操作。

    from flask import Flask, render_template
    ​
    app = Flask(__name__)
    ​
    # 自界说反常处理
    @app.errorhandler(404)
    def page_not_found(error):
       return render_template('404.html'), 404# 自界说反常处理
    @app.errorhandler(500)
    def server_error(error):
       return render_template('500.html'), 500if __name__ == '__main__':
       app.run()
    

    在上面的示例中,咱们界说了两个自界说反常处理函数,分别用于处理HTTP 404(页面未找到)和HTTP 500(服务器过错)过错。当这些过错产生时,Flask将调用相应的反常处理函数,然后回来自界说的过错页面。

    运用tryexcept句子

    您还能够运用Python的tryexcept句子来捕获和处理特定代码块中产生的反常。这关于处理非HTTP反常或特定操作的反常十分有用。

    from flask import Flask, render_template
    ​
    app = Flask(__name__)
    ​
    @app.route('/divide/<int:num>')
    def divide_by_zero(num):
       try:
         result = 10 / num
         return f'Result: {result}'
       except ZeroDivisionError:
         return 'Cannot divide by zero.'if __name__ == '__main__':
       app.run()
    

    在上面的示例中,咱们创立了一个路由 /divide/,然后在路由处理函数中运用 tryexcept 来捕获除以零的反常。假如用户供给的 num 值为零,将捕获 ZeroDivisionError 并回来相应的过错音讯。

    运用大局反常处理

    您还能够设置大局反常处理函数,以捕获未处理的反常。这能够用于处理运用中的通用过错状况。

    from flask import Flask, render_template
    ​
    app = Flask(__name__)
    ​
    # 大局反常处理
    @app.errorhandler(Exception)
    def handle_exception(error):
       return render_template('error.html', error=error), 500if __name__ == '__main__':
       app.run()
    

    在上面的示例中,咱们界说了一个大局反常处理函数,该函数会捕获任何未被其他反常处理函数捕获的反常。然后,咱们回来一个通用的过错页面,显现反常信息。

    经过运用这些反常处理办法,您能够更好地办理和处理Flask运用中的反常状况,供给更好的用户体会,一起增强运用的稳定性和安全性。在实践运用中,您能够依据需求创立更多的自界说反常处理函数,以应对特定的过错状况。

2. Flask高档开发

2.1 flask的恳求钩子详解

Flask的恳求钩子(Request Hooks)是一种机制,答应您在每个HTTP恳求的不同阶段履行自界说代码。这些钩子函数可用于在恳求处理进程中增加额定的逻辑、验证恳求、处理前后业务等。Flask供给了以下四种首要的恳求钩子:

  1. before_request 在恳求被分发给视图函数之前履行。这是一个大局性的恳求钩子,适用于一切恳求。
  2. before_first_request 在处理第一个恳求之前履行。一般用于履行运用程序的初始化或设置使命,这些使命只需求在运用程序发动时履行一次。
  3. after_request 在每个恳求被视图函数处理完毕后履行。该钩子函数能够检查呼应、增加额定的呼应头、修正呼应数据等操作。
  4. teardown_request 在每个恳求的最终阶段履行,即在呼应发送给客户端后。一般用于整理资源、封闭数据库衔接等。

以下是怎么运用这些恳求钩子的具体解说:

before_request

before_request钩子用于在每个恳求被分发到视图函数之前履行,能够用于身份验证、恳求预处理等使命。

from flask import Flask, request
​
app = Flask(__name__)
​
@app.before_request
def before_request():
   # 在此处履行恳求前的逻辑
   pass@app.route('/')
def index():
   return 'Hello, World!'if __name__ == '__main__':
   app.run()
before_first_request

before_first_request钩子只在运用程序初次处理恳求时履行,一般用于运用程序的初始化设置。

from flask import Flask
​
app = Flask(__name__)
​
@app.before_first_request
def before_first_request():
   # 运用程序初始化逻辑,只在第一个恳求时履行
   pass@app.route('/')
def index():
   return 'Hello, World!'if __name__ == '__main__':
   app.run()
after_request

after_request钩子在每个恳求的视图函数处理完毕后履行,能够用于修正呼应或增加额定的呼应头。

from flask import Flask
​
app = Flask(__name__)
​
@app.route('/')
def index():
   response = 'Hello, World!'
   return response
​
@app.after_request
def after_request(response):
   # 在此处履行呼应后的逻辑
   response.headers['X-Custom-Header'] = 'Custom Value'
   return response
​
if __name__ == '__main__':
   app.run()
teardown_request

teardown_request钩子在每个恳求的最终阶段履行,一般用于整理资源或履行其他整理操作。

from flask import Flask
​
app = Flask(__name__)
​
@app.route('/')
def index():
   return 'Hello, World!'@app.teardown_request
def teardown_request(exception=None):
   # 在此处履行整理逻辑
   passif __name__ == '__main__':
   app.run()

这些恳求钩子答应您以十分灵敏的办法扩展和自界说Flask运用程序的行为。您能够依据需求运用这些钩子来履行各种操作,从恳求前的身份验证到恳求后的呼应处理和整理。这供给了对恳求处理流程的强壮操控。

在Flask中,恳求钩子(Request Hooks)能够经过两种办法进行调用,分别是装修器办法和注册办法。这两种办法都答应您履行在恳求处理进程中的自界说逻辑,但它们的运用和用处略有不同。

装修器办法

装修器办法是最常见的运用恳求钩子的办法,它答应您将恳求钩子函数直接附加到视图函数上,以在每次恳求特定视图函数时履行。

from flask import Flask
​
app = Flask(__name__)
​
@app.before_request
def before_request():
   # 在恳求前履行的逻辑
   pass@app.route('/')
def index():
   # 视图函数
   return 'Hello, World!'if __name__ == '__main__':
   app.run()

在上面的示例中,@app.before_request 装修器将 before_request 函数运用到了 / 路由对应的视图函数上。这意味着在每次拜访 / 路由时,before_request 函数都会在视图函数之前被调用。

注册办法

注册办法答应您在运用程序等级注册恳求钩子函数,以在一切视图函数履行之前或之后履行。这一般在运用的大局装备中运用。

from flask import Flask
​
app = Flask(__name__)
​
def before_request():
   # 在恳求前履行的逻辑
   pass
​
app.before_request(before_request)
​
@app.route('/')
def index():
   # 视图函数
   return 'Hello, World!'if __name__ == '__main__':
   app.run()

在上面的示例中,咱们首要界说了 before_request 函数,然后运用 app.before_request(before_request) 注册了这个函数。这样,在每次恳求任何视图函数之前,before_request 函数都会被调用。

总结来说,两种办法都能够用于履行恳求钩子,挑选运用哪种办法取决于您的需求。装修器办法更灵敏,答应您将恳求钩子函数与特定视图函数相关,而注册办法更合适在运用程序等级履行通用的恳求前逻辑。依据具体状况,您能够挑选运用一种或两种办法来办理恳求钩子。

2.2 蓝图的运用

2.2.1 运用

进程1: 创立蓝图方针

首要,咱们将在子模块中创立蓝图方针。假定您有两个子模块,一个名为auth,另一个名为api。以下是每个子模块中的__init__.py文件,用于创立蓝图方针:

auth/init .py – 创立auth_bp蓝图方针

# auth/__init__.pyfrom flask import Blueprint
​
# 创立蓝图方针
auth_bp = Blueprint('auth', __name__)
​
# 导入视图函数,以便在此文件中注册路由
from . import views

进程2: 运用蓝图方针绑定路由和视图函数

接下来,咱们在每个子模块中的views.py文件中界说视图函数并运用蓝图方针绑定路由。

auth/views.py – 界说auth子模块的视图函数

# auth/views.py
​
from flask import jsonify
from . import auth_bp  # 导入蓝图方针# 示例API路由和视图函数
@auth_bp.route('/login', methods=['POST'])
def login():
   # 处理登录逻辑
   username = request.json.get('username')
   password = request.json.get('password')
   # 假定在这儿进行用户验证等操作
   if username == 'user' and password == 'password':
     response_data = {'message': 'Login successful'}
   else:
     response_data = {'message': 'Login failed'}
   return jsonify(response_data)

api/views.py – 界说api子模块的视图函数

# api/views.pyfrom flask import jsonify
from . import api_bp  # 导入蓝图方针# 示例API路由和视图函数
@api_bp.route('/api/data', methods=['GET'])
def get_data():
   data = {'message': 'Hello, this is API data!'}
   return jsonify(data)

进程3: 在app中注册蓝图方针

最终,咱们在主运用的app.py文件中注册蓝图方针,使其成为主运用的一部分。

app.py – 主运用文件

# app.py
​
from flask import Flask
from auth import auth_bp  # 导入auth子模块的蓝图方针
from api import api_bp   # 导入api子模块的蓝图方针app = Flask(__name__)
​
# 注册auth子模块的蓝图,设置URL前缀为/auth
app.register_blueprint(auth_bp, url_prefix='/auth')
​
# 注册api子模块的蓝图,设置URL前缀为/api
app.register_blueprint(api_bp, url_prefix='/api')
​
if __name__ == '__main__':
   app.run()

在主运用app.py中,咱们导入了auth_bpapi_bp蓝图方针,并运用app.register_blueprint()办法将它们注册到主运用中。分别为/auth/api设置了URL前缀,以便在主运用中运用这些蓝图中界说的路由。

这个示例展现了怎么依照您供给的进程创立蓝图方针、绑定路由和视图函数,并在主运用中注册蓝图方针,以便构建一个安排杰出的Flask运用程序。每个子模块能够包含自己的路由和视图函数,完结模块化开发。

url_prefix

url_prefix是在注册蓝图方针时可选的参数,它用于为整个蓝图中界说的路由增加一个共同的URL前缀。这是一种很有用的办法,能够在主运用中安排和命名不同的子模块。

让咱们持续运用前面的示例来演示怎么运用url_prefix装备:

假定您有两个子模块,一个是auth,另一个是api,而且您想为每个子模块增加URL前缀,以便在主运用中区分它们的路由。

auth子模块的__init__.py

# auth/__init__.pyfrom flask import Blueprint
​
# 创立蓝图方针
auth_bp = Blueprint('auth', __name__)
​
# 导入视图函数,以便在此文件中注册路由
from . import views

api子模块的__init__.py

# api/__init__.pyfrom flask import Blueprint
​
# 创立蓝图方针
api_bp = Blueprint('api', __name__)
​
# 导入视图函数,以便在此文件中注册路由
from . import views

在主运用中注册蓝图方针:

# app.py
​
from flask import Flask
from auth import auth_bp
from api import api_bp
​
app = Flask(__name__)
​
# 注册auth子模块的蓝图,设置URL前缀为/auth
app.register_blueprint(auth_bp, url_prefix='/auth')
​
# 注册api子模块的蓝图,设置URL前缀为/api
app.register_blueprint(api_bp, url_prefix='/api')
​
if __name__ == '__main__':
   app.run()

在上述示例中,咱们运用了url_prefix参数来设置不同子模块的URL前缀。关于auth子模块,路由前缀为/auth,关于api子模块,路由前缀为/api。这意味着在主运用中拜访/auth/login将调用auth子模块中的login视图函数,而拜访/api/api/data将调用api子模块中的get_data视图函数。

运用url_prefix装备能够有用地安排和办理不同子模块的路由,使代码更具结构性和可读性。这关于大型运用程序特别有用。

2.2.2 url_for

url_for 是 Flask 中的一个十分有用的函数,它用于生成 URL,特别是用于构建视图函数的 URL。它的首要作用是使您的运用愈加可保护和灵敏,由于它答应您经过视图函数的称号而不是硬编码的 URL 来构建链接。

以下是关于 url_for 函数的具体解说:

根本语法

url_for(endpoint, **kwargs)
  • endpoint: 视图函数的称号(字符串),或许 Flask 蓝图中的视图函数称号。
  • **kwargs: 要害字参数,用于传递视图函数的参数。
2.2.3 怎么运用 url_for

假定您有一个名为 hello 的视图函数,能够运用 url_for 来生成链接到该视图函数的 URL:

from flask import Flask, url_for
​
app = Flask(__name__)
​
@app.route('/')
def hello():
   return 'Hello, World!'if __name__ == '__main__':
   with app.test_request_context():
     print(url_for('hello'))  # 生成到 hello 视图函数的 URL

在上面的示例中,url_for('hello') 会生成链接到 hello 视图函数的 URL。在实践运用中,这个链接或许是依据路由规矩和参数生成的。

传递参数

假如视图函数需求接收参数,您能够在 url_for 中传递这些参数,如下所示:

@app.route('/user/<username>')
def profile(username):
   return f'User profile: {username}'with app.test_request_context():
   print(url_for('profile', username='john'))

在这个示例中,咱们有一个 profile 视图函数,承受一个 username 参数。经过 url_for('profile', username='john'),咱们能够生成链接到该视图函数的 URL,并将 username 参数传递给它。

运用蓝图

假如您的运用运用了 Flask 蓝图,您能够在 url_for 中指定蓝图的称号和视图函数的称号,以生成链接到蓝图中的视图函数的 URL。例如:

from flask import Blueprint
​
auth_bp = Blueprint('auth', __name__)
​
@auth_bp.route('/login')
def login():
   return 'Login page'with app.test_request_context():
   print(url_for('auth.login'))

在这个示例中,咱们创立了一个 auth 蓝图,并界说了一个 login 视图函数。经过 url_for('auth.login'),咱们能够生成链接到 auth.login 视图函数的 URL。

总归,url_for 函数是 Flask 中的一个十分有用的东西,它答应您以愈加动态和可保护的办法生成链接到视图函数的 URL。这在构建具有杂乱路由结构的运用程序时特别有用。

2.3 上下文

在 Flask 中,上下文是一个要害的概念,它用于盯梢和办理恳求和应对的相关信息,使您能够在运用程序的不同部分拜访这些信息。Flask 供给了两种首要类型的上下文:运用上下文(Application Context)和恳求上下文(Request Context)。

运用上下文(Application Context)

运用上下文表明整个 Flask 运用程序的生命周期,一般在运用程序发动时创立,并在运用程序封闭时毁掉。它包含了大局装备、Flask 扩展方针、路由信息等运用等级的信息。

在运用上下文中,您能够拜访运用程序等级的变量和方针,例如运用装备、数据库衔接、日志记载器等。一般,运用上下文是线程安全的,由于每个线程都有自己的运用上下文。

恳求上下文(Request Context)

恳求上下文是与每个客户端恳求相关的上下文,它包含了恳求和呼应方针、恳求等级的变量、当时用户等信息。恳求上下文在每个 HTTP 恳求到达运用程序时创立,并在恳求处理完结后毁掉。

在恳求上下文中,您能够拜访与特定恳求相关的信息,例如恳求头、恳求参数、表单数据、Cookies 等。恳求上下文答应您在不同恳求之间阻隔数据,保证并发恳求之间不会相互搅扰。

上下文办理

Flask 供给了上下文办理器来办理上下文的创立和毁掉。一般,您不需求手动创立或毁掉上下文,Flask 会在恳求到达时主动创立恳求上下文,恳求处理完毕后毁掉它。

但在某些状况下,或许需求手动操作上下文,例如在测验中运用上下文办理器来模仿恳求。Flask 供给了 app.app_context()app.test_request_context() 上下文办理器,使您能够手动办理运用上下文和恳求上下文。

以下是一个简略的示例,展现了怎么运用上下文办理器来手动创立运用上下文和恳求上下文:

from flask import Flask
​
app = Flask(__name__)
​
# 运用 app.app_context() 创立运用上下文
with app.app_context():
   # 在运用上下文中能够拜访运用等级的信息
   app.config['DEBUG'] = True
   print(app.config['DEBUG'])
​
# 运用 app.test_request_context() 创立恳求上下文
with app.test_request_context('/some-url', method='POST'):
   # 在恳求上下文中能够拜访恳求等级的信息
   print(request.path)
   print(request.method)

在上述示例中,咱们运用 app.app_context() 创立运用上下文,并在其间拜访运用等级的装备信息。然后,运用 app.test_request_context() 创立恳求上下文,并在其间模仿了一个 POST 恳求,以便拜访恳求等级的信息。

总归,上下文是 Flask 中的重要概念,它有助于在运用程序中盯梢和办理恳求和应对的相关信息。了解上下文怎么作业以及怎么运用上下文办理器能够协助您更好地构建和了解 Flask 运用程序。

怎么运用上下文在钩子函数与视图函数之间传参

在 Flask 中,您能够运用上下文来在钩子函数(如 before_requestbefore_first_request 等)和视图函数之间传递参数。一种常见的办法是将数据存储在恳求上下文(request 上下文方针)中,以便在不同部分的恳求处理进程中拜访它。

下面是一个示例,演示怎么在钩子函数和视图函数之间传递参数:

from flask import Flask, request, g
​
app = Flask(__name__)
​
# 在 before_request 钩子函数中设置数据到恳求上下文
@app.before_request
def before_request():
   g.user = 'John'  # 假定在这儿获取了用户信息# 在视图函数中拜访恳求上下文中的数据
@app.route('/')
def hello():
   user = g.user  # 从恳求上下文中获取用户信息
   return f'Hello, {user}!'if __name__ == '__main__':
   app.run()

在上述示例中,咱们运用 @app.before_request 钩子函数在每个恳求处理之前设置了一个 g.user 变量,表明当时用户。然后,在视图函数中,咱们能够经过 g.user 来拜访这个用户信息。

经过这种办法,您能够在钩子函数中履行一些预处理操作,例如身份验证、权限检查、用户会话办理等,并将相关信息传递给视图函数,而不需求显式传递参数。这样能够使代码愈加整洁和可保护。

请注意,g 方针(request 上下文中的大局方针)在每个恳求上下文中都是独立的,不同恳求之间不会相互搅扰。因而,您能够在钩子函数中设置和拜访这些数据,而不用担心并发恳求之间的抵触。

3. 完结登录鉴权

要完结用户登录鉴权,您能够运用装修器和上下文来保证只要已登录的用户才干拜访某些接口。以下是一个示例,演示怎么运用装修器来完结这一功用:

from flask import Flask, request, g
​
app = Flask(__name__)
​
# 假定的用户数据
users = {
   'user1': {'username': 'user1', 'password': 'password1'},
   'user2': {'username': 'user2', 'password': 'password2'},
}
​
# 在 before_request 钩子函数中进行用户登录鉴权
@app.before_request
def before_request():
   # 获取用户身份信息,这儿简略演示,实践运用中或许需求更安全的办法来获取用户信息
   g.user = None
   if 'username' in request.cookies:
     username = request.cookies['username']
     if username in users:
       g.user = users[username]
​
# 登录装修器
def login_required(view_func):
   def wrapper(*args, **kwargs):
     if g.user is None:
       return 'Unauthorized', 401  # 未登录回来未授权状况码
     return view_func(*args, **kwargs)
   return wrapper
​
# 被保护的点赞接口
@app.route('/like', methods=['POST'])
@login_required  # 运用装修器进行登录鉴权
def like():
   # 在这儿处理点赞逻辑
   return 'Liked'# 被保护的保藏接口
@app.route('/favorite', methods=['POST'])
@login_required  # 运用装修器进行登录鉴权
def favorite():
   # 在这儿处理保藏逻辑
   return 'Favorited'if __name__ == '__main__':
   app.run()

在上述示例中,咱们首要界说了一个用户数据字典 users,用于存储用户信息。然后,在 before_request 钩子函数中,咱们检查恳求中的 username Cookie,假如存在而且在用户数据中,则以为用户已登录,将用户信息存储在 g.user 中。

接下来,咱们界说了一个名为 login_required 的装修器,该装修器会检查用户是否已登录。假如用户未登录,装修器会回来未授权的 HTTP 状况码(401)。

最终,咱们界说了两个被保护的接口 /like/favorite,并运用 @login_required 装修器来保护它们。这意味着只要已登录的用户才干拜访这些接口,否则会收到未授权的呼应。

请注意,这仅仅一个简略的示例,实践运用中,您或许需求更安全的用户身份验证机制,例如运用 JWT(JSON Web Token)或 OAuth 2.0 来保证用户身份的安全性。此外,用户数据的存储和验证也应该愈加杂乱和安全。

4. 装修器详解

装修器是 Python 中的一种高档功用,它答应您修正或扩展函数或办法的行为,而无需修正其源代码。装修器一般用于增加额定的功用、验证或修正函数的输入或输出,或许履行与函数相关的其他使命。

下面我将尽量以简略、明晰、明了的办法来解说装修器,并供给一些实践项目中常见的例子。

装修器的根本结构

装修器是函数,它承受一个函数作为参数,并回来一个新的函数。一般的结构如下:

def decorator_function(original_function):
   def wrapper_function(*args, **kwargs):
     # 在调用原始函数之前能够增加额定的功用
     result = original_function(*args, **kwargs)
     # 在调用原始函数之后也能够增加额定的功用
     return result
   return wrapper_function

装修器的运用

装修器运用 @ 符号来运用到函数上,它在函数界说之前运用,如下所示:

@decorator_function
def some_function():
   # 函数的主体部分

简略的装修器示例

让咱们从一个简略的装修器示例开端,用于丈量函数的履行时刻:

import time
​
# 装修器函数,用于丈量函数履行时刻
def timing_decorator(func):
   def wrapper(*args, **kwargs):
     start_time = time.time()
     result = func(*args, **kwargs)
     end_time = time.time()
     print(f"{func.__name__} 履行时刻: {end_time - start_time} 秒")
     return result
   return wrapper
​
# 运用装修器到函数
@timing_decorator
def slow_function():
   time.sleep(2)
   print("slow_function 履行完毕")
​
# 调用带有装修器的函数
slow_function()

在这个示例中,timing_decorator 装修器用于丈量函数履行时刻。当咱们运用装修器到 slow_function 上时,它会在函数开端前记载时刻,履行函数,然后在函数完毕后记载时刻,最终输出函数的履行时刻。

装修器在项目中的运用

在实践项目中,装修器能够用于以下状况:

  1. 身份验证和权限操控:保证用户已登录或具有特定权限才干拜访某些页面或功用。
  2. 日志记载:记载函数的履行时刻、输入和输出,以便进行调试和功用优化。
  3. 缓存:将函数的成果缓存起来,以削减重复核算或数据库查询。
  4. 过错处理:捕获函数中的反常,记载过错信息,或许履行其他处理操作。
  5. 业务办理:在数据库操作中办理业务,保证数据的共同性和完好性。
  6. 路由注册:将路由与视图函数相关起来,以完结 Web 结构中的路由处理。
  7. 功用优化:对函数进行功用剖析,查找瓶颈并进行优化。

这些是装修器的一些常见用处,它们使得代码更具可读性和可保护性,一起供给了一种模块化和可扩展的办法来增加功用到函数中。在实践项目中,您或许会创立多个自界说装修器,以满意不同的需求。

事例

1. 身份验证装修器

from functools import wraps
from flask import request, redirect, url_for
​
# 身份验证装修器
def login_required(view_func):
   @wraps(view_func)
   def wrapper(*args, **kwargs):
     if not current_user.is_authenticated:
       return redirect(url_for('login'))
     return view_func(*args, **kwargs)
   return wrapper
​
# 运用装修器保护需求登录才干拜访的路由
@app.route('/dashboard')
@login_required
def dashboard():
   return 'Welcome to the dashboard!'

在上述示例中,login_required 装修器用于保证用户已登录。假如用户未登录,他们将被重定向到登录页面。这个装修器能够运用于需求身份验证的任何路由。

2. 日志记载

import logging
​
# 日志记载装修器
def log_execution_time(view_func):
   @wraps(view_func)
   def wrapper(*args, **kwargs):
     start_time = time.time()
     result = view_func(*args, **kwargs)
     end_time = time.time()
     execution_time = end_time - start_time
     logging.info(f'{view_func.__name__} executed in {execution_time:.

3.缓存装修器

缓存装修器用于将函数的成果缓存起来,以防止重复核算或频繁的数据库查询。这关于进步功用和削减资源消耗十分有用。以下是一个运用装修器完结函数成果缓存的示例:

import functools
​
# 缓存装修器
def cache_result(view_func):
   cache = {}  # 缓存字典
​
   @functools.wraps(view_func)
   def wrapper(*args, **kwargs):
     # 构造缓存键,能够依据函数参数生成仅有的键
     cache_key = (args, frozenset(kwargs.items()))
​
     # 假如缓存中存在成果,直接回来
     if cache_key in cache:
       return cache[cache_key]
​
     # 否则,调用原始函数,并将成果缓存起来
     result = view_func(*args, **kwargs)
     cache[cache_key] = result
     return result
​
   return wrapper
​
# 运用缓存装修器
@cache_result
def expensive_calculation(x, y):
   # 模仿耗时核算
   result = x + y
   return result

在上述示例中,cache_result 装修器用于缓存函数 expensive_calculation 的成果。装修器会检查是否现已核算过给定参数的成果,假如现已核算过,则直接回来缓存的成果,否则履行函数核算,并将成果存入缓存。

这个装修器可用于各种需求缓存成果的状况,例如频繁的核算、数据库查询或网络恳求,以防止重复作业,进步功用。

示例运用办法:

pythonCopy coderesult1 = expensive_calculation(2, 3)  # 核算并缓存成果
result2 = expensive_calculation(2, 3)  # 直接从缓存获取成果
result3 = expensive_calculation(4, 5)  # 核算并缓存新的成果

在这个示例中,result1result2 将具有相同的值,由于第2次调用时直接从缓存中获取了成果,而 result3 将是新的核算成果。这样能够有用地削减重复核算的开支。

4.业务办理装修器

业务办理装修器用于在数据库操作中办理业务,以保证数据的共同性和完好性。业务是一组操作,要么悉数成功履行,要么悉数失利并回滚到之前的状况,以保证数据库的共同性。以下是一个运用装修器来办理数据库业务的示例:

pythonCopy codefrom functools import wraps
from sqlalchemy.exc import IntegrityError
from my_database import db
​
# 业务办理装修器
def transactional(view_func):
   @wraps(view_func)
   def wrapper(*args, **kwargs):
     try:
       result = view_func(*args, **kwargs)
       db.session.commit()  # 提交业务
       return result
     except IntegrityError:
       db.session.rollback()  # 回滚业务
       return 'Integrity error occurred', 400  # 客户端过错状况码
   return wrapper
​
# 运用业务办理装修器
@app.route('/add_user', methods=['POST'])
@transactional
def add_user():
   user = User(name='Alice', email='alice@example.com')
   db.session.add(user)
   return 'User added successfully'

在上述示例中,transactional 装修器用于办理数据库业务。假如在增加用户时产生完好性过错(例如,仅有键抵触),装修器会回滚业务并回来客户端过错呼应。

这个装修器十分有用,由于它保证了在数据库操作中的一组操作要么悉数成功提交,要么悉数回滚,以保护数据库的共同性和完好性。这在需求对数据库进行杂乱操作或多个操作的状况下特别重要。

5.过错处理装修器

过错处理装修器用于捕获函数中的反常,记载过错信息,或许履行其他处理操作,以进步运用的可靠性和容错性。以下是一个运用装修器来处理反常的示例:

import logging
​
# 过错处理装修器
def error_handler(view_func):
   @functools.wraps(view_func)
   def wrapper(*args, **kwargs):
     try:
       return view_func(*args, **kwargs)
     except Exception as e:
       # 在这儿记载过错信息
       logging.error(f"Error in {view_func.__name__}: {str(e)}")
       # 履行其他处理操作,例如回来一个过错呼应
       return "An error occurred", 500  # 500 表明服务器过错
   return wrapper
​
# 运用过错处理装修器
@app.route('/divide')
@error_handler
def divide():
   result = 10 / 0  # 引发除零反常
   return str(result)

在上述示例中,error_handler 装修器用于捕获函数 divide 中的反常。假如函数中产生反常,装修器会记载过错信息并回来一个过错呼应(HTTP 状况码 500 表明服务器过错)。

您能够依据需求自界说装修器的行为,例如记载过错信息、发送警报、回滚业务等。这有助于进步运用的稳定性和可保护性,一起能够更简略地处理反常状况。

6.路由注册装修器

from flask import Flask, Blueprint
​
app = Flask(__name__)
api = Blueprint('api', __name__)
​
# 路由注册装修器
def route(url):
   def decorator(view_func):
     @api.route(url)
     @wraps(view_func)
     def wrapper(*args, **kwargs):
       return view_func(*args, **kwargs)
     return wrapper
   return decorator
​
# 运用装修器注册路由
@route('/user/<int:user_id>')
def get_user(user_id):
   # 回来用户信息
   return f'User {user_id} details'# 在运用中注册蓝图
app.register_blueprint(api, url_prefix='/api')

在上述示例中,route 装修器用于注册路由。它将路由 URL 作为参数,并将视图函数与路由相关起来。然后,咱们在运用中注册了一个包含这些路由的蓝图。

7.功用优化装修器

import time
​
# 功用优化装修器
def profile(view_func):
   @wraps(view_func)
   def wrapper(*args, **kwargs):
     start_time = time.time()
     result = view_func(*args, **kwargs)
     end_time = time.time()
     execution_time = end_time - start_time
     if execution_time > 1.0:
       print(f'{view_func.__name__} took {execution_time:.2f} seconds')
     return result
   return wrapper
​
# 运用装修器进行功用剖析
@app.route('/slow_endpoint')
@profile
def slow_endpoint():
   time.sleep(2)  # 模仿慢速操作
   return 'Slow endpoint executed'

在上述示例中,profile 装修器用于功用剖析。假如函数的履行时刻超过 1 秒,它会打印一条音讯以警告慢速履行。

这些示例展现了怎么运用装修器来增加各种功用到函数中,以满意不同的需求。装修器能够进步代码的可读性和可保护性,一起使代码更模块化和可重用。在项目中,您能够依据需求创立自界说装修器来满意特定的功用要求。

5. flask运用装备

在Flask中,运用装备十分重要,它答应您界说运用程序的行为,例如数据库衔接、密钥、调试办法等。Flask供给了一个名为config的方针,用于办理运用装备。以下是关于Flask运用装备的具体解说以及一个实践的商业事例。

5.1Flask运用装备的根本概念:

在Flask中,运用装备运用Python字典来表明。您能够在运用程序中运用这些装备来操控运用程序的行为。

  1. 装备方针创立:在Flask运用中,您能够创立一个装备方针,一般称为app.config。这个装备方针是一个字典,包含了各种装备项的键值对。
  2. 装备项:装备项是装备方针中的键,用于拜访特定装备的值。例如,您能够运用app.config['DEBUG']来获取调试办法的装备值。
  3. 设置装备项:您能够在运用程序中经过多种办法设置装备项,包含从文件加载、从环境变量中读取、或直接在运用程序代码中硬编码。

5.2Flask运用装备的实践商业事例:

假定您正在开发一个电子商务网站的后端,以下是一些常见的装备项以及相应的商业事例:

  1. 数据库装备:装备数据库衔接信息,包含数据库的地址、用户名和暗码。这答应您衔接到数据库并履行数据操作。

    app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://username:password@localhost/mydatabase'
    
  2. 密钥装备:装备运用程序的安全密钥,用于加密用户会话和保护数据。

    app.config['SECRET_KEY'] = 'mysecretkey'
    
  3. 调试办法装备:在开发期间启用调试办法,以便在呈现过错时获得具体的过错信息。

    app.config['DEBUG'] = True
    
  4. 日志装备:装备日志记载,以便盯梢运用程序的活动和过错,以便进行故障扫除。

    app.config['LOGGING_LEVEL'] = 'DEBUG'
    
  5. 文件上传装备:装备文件上传的最大巨细和答应的文件类型。

    app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16MB
    app.config['ALLOWED_EXTENSIONS'] = {'jpg', 'png', 'gif'}
    

这些装备项能够依据您的具体运用程序需求进行调整。在运用程序中,您能够随时拜访这些装备项以获取其值,例如:

db_uri = app.config['SQLALCHEMY_DATABASE_URI']

经过运用装备,您能够轻松地办理运用程序的行为,以习惯不同的环境和需求,然后使您的Flask运用愈加灵敏和可保护。

5.3经过环境变量装备

经过环境变量装备是一种常见的办法,用于在不同环境中设置和办理Flask运用程序的装备。这使您能够轻松地切换装备,而无需修正运用程序代码。以下是怎么经过环境变量装备Flask运用程序的进程以及一个实践的商业事例:

进程:
  1. 在运用程序中导入os模块:首要,您需求导入Python的os模块,以便能够拜访环境变量。

    import os
    
  2. 界说默许装备:在您的Flask运用程序中,界说一个包含默许装备的字典。这将作为备选装备,以防环境变量未设置时运用。

    app.config['DEBUG'] = False
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
    
  3. 从环境变量读取装备:在运用程序初始化时,运用os.environ.get()办法来读取环境变量,并将其设置为相应的装备项。

    app.config['DEBUG'] = os.environ.get('FLASK_DEBUG', False)
    app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'sqlite:///mydatabase.db')
    

    这儿,FLASK_DEBUGDATABASE_URL 是您要设置的环境变量称号。

  4. 设置环境变量:在布置运用程序时,您能够经过操作体系的办法来设置环境变量。不同操作体系设置环境变量的办法略有不同。例如,在Linux/macOS中,您能够在终端中运用export指令来设置环境变量:

    export FLASK_DEBUG=True
    export DATABASE_URL=postgresql://username:password@localhost/mydatabase
    

    在Windows中,您能够运用set指令来设置环境变量:

    set FLASK_DEBUG=True
    set DATABASE_URL=postgresql://username:password@localhost/mydatabase
    
商业事例:

假定您的Flask运用程序需求在开发和出产环境中运用不同的数据库衔接。您能够运用环境变量装备来完结这一方针。

在开发环境中,您能够设置环境变量如下:

export FLASK_DEBUG=True
export DATABASE_URL=sqlite:///development.db

在出产环境中,您能够设置不同的环境变量:

export FLASK_DEBUG=False
export DATABASE_URL=postgresql://username:password@productionserver/productiondb

经过这种办法,您能够轻松切换运用程序的装备,而无需修正代码,然后保证在不同环境中运转您的Flask运用程序时,运用正确的装备。这在布置到不同服务器或云平台时特别有用。

5.4 经过装备类装备

在Flask中,您能够经过创立一个装备类来加载装备信息,这是一种更结构化和可保护的办法,特别适用于大型运用程序。以下是怎么经过装备类加载装备信息的进程以及一个实践的商业事例:

进程:

  1. 创立一个装备类:首要,您需求创立一个Python类,用于存储运用程序的装备信息。这个类一般承继自Flask的Config类,或许您也能够直接运用一个普通的Python类。在这个类中,您能够界说各种装备项作为类特色。

    class Config:
       DEBUG = False
       SQLALCHEMY_DATABASE_URI = 'sqlite:///mydatabase.db'
       SECRET_KEY = 'mysecretkey'
    
  2. 在运用程序中加载装备:在Flask运用程序初始化时,将装备类的装备项加载到运用程序中。

    app = Flask(__name__)
    app.config.from_object(Config)
    

    这儿,from_object 办法将装备项从装备类中加载到运用程序的装备中。

商业事例:

假定您正在开发一个社交媒体平台的后端运用程序。不同的装备类能够协助您在不同环境中办理不同的装备,如开发、测验和出产环境。

class DevelopmentConfig:
   DEBUG = True
   SQLALCHEMY_DATABASE_URI = 'sqlite:///development.db'
   SECRET_KEY = 'devsecretkey'
​
class TestingConfig:
   TESTING = True
   SQLALCHEMY_DATABASE_URI = 'sqlite:///test.db'
   SECRET_KEY = 'testsecretkey'
​
class ProductionConfig:
   DEBUG = False
   SQLALCHEMY_DATABASE_URI = 'postgresql://username:password@productionserver/productiondb'
   SECRET_KEY = 'prodsecretkey'

在运用程序初始化时,依据不同的环境挑选加载不同的装备类:

app = Flask(__name__)
​
# 针对不同环境加载不同的装备类
if app.config['ENV'] == 'development':
   app.config.from_object(DevelopmentConfig)
elif app.config['ENV'] == 'testing':
   app.config.from_object(TestingConfig)
else:
   app.config.from_object(ProductionConfig)

这种办法使您能够在不同环境中轻松办理和切换装备,并使您的运用程序更易于保护。在不同环境中运用不同的装备,例如不同的数据库衔接和密钥,有助于保证运用程序在不同状况下都能正常运转。

6. flask-restful扩展运用

Flask-RESTful是一个用于构建RESTful API的Flask扩展,它使得创立API变得愈加简略和规范化。

构建流程

1. 创立扩展/组件方针

在运用Flask-RESTful构建API之前,您需求创立Flask运用并初始化Flask-RESTful扩展。扩展方针将用于创立和办理API资源。以下是创立扩展方针的进程:

进程1:创立Flask运用

首要,创立一个Flask运用。

from flask import Flask
app = Flask(__name__)

进程2:初始化Flask-RESTful扩展

接下来,初始化Flask-RESTful扩展,并将其与Flask运用相关。

from flask_restful import Api
api = Api(app)
2. 界说类视图

在Flask-RESTful中,API资源一般由类视图表明。类视图是Python类,承继自Resource类,并界说了API端点的HTTP办法(GET、POST、PUT、DELETE等)以及它们的行为。以下是界说类视图的进程:

进程3:界说类视图

创立一个类视图,界说HTTP办法和相应的处理逻辑。这儿是一个示例:

from flask_restful import Resource
class HelloWorld(Resource):
    def get(self):
        return {'message': 'Hello, World!'}
3. 组件增加类视图

最终,将类视图增加到Flask-RESTful扩展中,并将其相关到API端点的URL途径。这将使API端点可拜访。以下是将类视图增加到扩展的进程:

进程4:组件增加类视图

运用Flask-RESTful的add_resource办法将类视图增加到扩展,并指定URL途径。例如:

api.add_resource(HelloWorld, '/hello')

商业事例1:

假定您正在开发一个电子商务平台,您能够运用Flask-RESTful构建一个API端点,用于获取产品信息。以下是一个示例:

from flask import Flask
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
class ProductResource(Resource):
    def get(self, product_id):
        # 假定这儿有获取特定产品信息的逻辑
        product = get_product_by_id(product_id)
        if product:
            return product
        else:
            return {'message': 'Product not found'}, 404
    def post(self):
        # 假定这儿有创立新产品的逻辑
        data = request.json
        product = create_product(data)
        return product, 201
api.add_resource(ProductResource, '/products/<int:product_id>')
if __name__ == '__main__':
    app.run(debug=True)

在这个示例中,ProductResource类界说了一个用于获取和创立产品信息的API端点。经过Flask-RESTful的add_resource办法将它与URL途径相关,然后构建了一个RESTful API。这个API能够用于客户端运用程序,例如网站或移动运用,以获取和创立产品信息。

商业事例2:

假定您正在开发一个电子商务平台的后端,您能够运用Flask-RESTful来创立产品API。您能够创立一个资源类,表明产品,并界说GET、POST、PUT和DELETE办法来处理产品的操作。

class ProductResource(Resource):
    def get(self, product_id):
        # 回来特定产品的信息
        product = get_product_by_id(product_id)
        if product:
            return product
        else:
            return {'message': 'Product not found'}, 404
    def post(self):
        # 创立新的产品
        data = request.json
        product = create_product(data)
        return product, 201
    def put(self, product_id):
        # 更新特定产品的信息
        data = request.json
        product = update_product(product_id, data)
        return product
    def delete(self, product_id):
        # 删去特定产品
        delete_product(product_id)
        return '', 204
api.add_resource(ProductResource, '/products/<int:product_id>')

这个例子中,您能够运用ProductResource类来创立、获取、更新和删去产品信息。这使得您的电子商务平台能够经过API供给产品相关的操作,例如获取产品列表、创立新产品、更新产品信息以及删去产品。

7. Flask-RESTful 参数解析

参数解析是指从恳求中提取并验证参数的进程。在 Flask-RESTful 中,您能够运用 reqparse 模块来完结参数解析。以下是参数解析的流程:

  1. 创立参数解析方针:首要,您需求创立一个参数解析方针,一般称为 reqparse。您能够运用 reqparse.RequestParser() 来创立它。
  2. 界说参数:为要解析的参数界说称号、类型和协助信息。这些参数一般与恳求的 URL、查询字符串、表单数据或 JSON 数据相相关。
  3. 解析参数:运用 parse_args() 办法从恳求中提取参数,并依据界说的规矩进行验证。假如参数不契合规矩,将回来过错呼应。

以下是一个示例:

from flask_restful import reqparse
# 进程1:创立参数解析方针
parser = reqparse.RequestParser()
# 进程2:界说参数
parser.add_argument('name', type=str, required=True, help='Name of the item')
parser.add_argument('price', type=float, required=True, help='Price of the item')

在上面的示例中,咱们创立了一个参数解析方针 parser,并界说了两个参数:nameprice。这些参数在恳求中都是必需的,而且有相应的类型和协助信息。

# 进程3:解析参数
args = parser.parse_args()
自界说参数类型

在 Flask-RESTful 中,你能够自界说参数类型以处理特定的恳求参数。自界说参数类型答应你在恳求解析进程中履行自界说的验证、转换和处理逻辑。以下是一个示例,展现怎么创立自界说参数类型:

假定你想要创立一个自界说参数类型来处理 “年纪规模” 参数,该参数包含最小年纪和最大年纪。你想要验证这两个值,并在解析恳求时将它们转换为整数。

from flask_restful import reqparse, Resource
​
# 自界说参数类型处理年纪规模
def age_range(value):
   try:
     min_age, max_age = map(int, value.split('-'))
     if min_age >= 0 and max_age >= min_age:
       return min_age, max_age
     else:
       raise ValueError("Invalid age range")
   except ValueError:
     raise ValueError("Invalid age range")
​
# 创立恳求解析器
parser = reqparse.RequestParser()
parser.add_argument('age_range', type=age_range, required=True, help='Invalid age range format. Use min-max.')
​
class AgeRangeResource(Resource):
   def get(self):
     args = parser.parse_args()
     min_age, max_age = args['age_range']
     return {'min_age': min_age, 'max_age': max_age}
​
# 在 Flask-RESTful 中增加资源
api.add_resource(AgeRangeResource, '/age_range')
​
if __name__ == '__main__':
   app.run()

在上面的示例中,咱们首要界说了 age_range 函数,它用于处理 “age_range” 参数。此函数承受一个字符串,将其拆分为最小年纪和最大年纪,并验证它们是否有用。假如参数无效,它会引发 ValueError 反常。

然后,咱们运用 reqparse.RequestParser 创立一个参数解析器,将 age_range 参数增加到解析器中,并指定了自界说的参数类型 age_range。咱们还指定了参数的必要性和协助文本。

最终,咱们创立了一个资源类 AgeRangeResource,在该类中运用解析器来解析恳求,并回来最小年纪和最大年纪。这个资源能够增加到你的 Flask-RESTful 运用中,以处理 “age_range” 参数的恳求。

经过创立自界说参数类型,你能够在 Flask-RESTful 中处理各种杂乱的恳求参数,并保证它们在被运用之前经过验证和转换。

8. Flask-RESTful 序列化

序列化是指将呼应数据转换为特定格局的进程,一般是 JSON 格局。在 Flask-RESTful 中,您能够运用序列化来将 Python 方针转换为 JSON 数据以进行呼应。以下是序列化的流程:

  1. 界说资源类:首要,您需求创立一个资源类,一般承继自 Resource 类,来处理恳求并生成呼应数据。
  2. 生成呼应数据:在资源类中生成要呼应的数据,一般是 Python 字典或方针。
  3. 序列化呼应数据:运用 Flask-RESTful 供给的序列化办法将呼应数据转换为 JSON 格局。

以下是一个示例:

from flask_restful import Resource, fields, marshal_with
​
# 进程1:界说资源类
class ItemResource(Resource):
   # 进程2:生成呼应数据
   def get(self, item_id):
     item = get_item_by_id(item_id)
     if item:
       return item
     else:
       return {'message': 'Item not found'}, 404
​
# 进程3:序列化呼应数据
item_fields = {
   'id': fields.Integer,
   'name': fields.String,
   'price': fields.Float,
}
​
class ItemListResource(Resource):
   @marshal_with(item_fields)
   def get(self):
     items = get_all_items()
     return items

在上面的示例中,ItemResource 类处理获取单个项目的恳求,并回来项目数据。ItemListResource 类处理获取一切项目的恳求,并运用 marshal_with 装修器将呼应数据序列化为 JSON 格局。

9. Flask-RESTful 完好事例

from flask import Flask, request
from flask_restful import Resource, Api, reqparse, fields, marshal_with
app = Flask(__name__)
api = Api(app)
# 暂时存储订单数据的列表
orders = []
# 进程1:创立参数解析方针
order_parser = reqparse.RequestParser()
order_parser.add_argument('product_name', type=str, required=True, help='Name of the product')
order_parser.add_argument('quantity', type=int, required=True, help='Quantity of the product')
# 进程2:界说资源类
class OrderResource(Resource):
    # 创立订单
    def post(self):
        # 进程3:解析参数
        args = order_parser.parse_args()
        # 从恳求参数中获取产品称号和数量
        product_name = args['product_name']
        quantity = args['quantity']
        # 创立订单方针
        order = {'product_name': product_name, 'quantity': quantity}
        orders.append(order)
        return {'message': 'Order created successfully'}, 201
# 进程3:序列化呼应数据
order_fields = {
    'product_name': fields.String,
    'quantity': fields.Integer,
}
class OrderListResource(Resource):
    @marshal_with(order_fields)
    def get(self):
        # 获取订单列表
        return orders
# 增加资源类到API
api.add_resource(OrderResource, '/order')
api.add_resource(OrderListResource, '/orders')
if __name__ == '__main__':
    app.run(debug=True)

在这个示例中,咱们创立了两个资源类:OrderResource 用于创立订单,OrderListResource 用于获取订单列表。参数解析器 order_parser 用于解析创立订单恳求中的参数。order_fields 界说了订单数据的序列化格局。

商业事例:这个 API 答应客户端创立订单并获取订单列表。客户端能够经过向 /order 发送 POST 恳求来创立订单,需求供给产品称号和数量。然后,客户端能够向 /orders 发送 GET 恳求来获取订单列表。这个 API 能够用于在线商铺的订单办理体系,客户能够创立订单并检查自己的订单历史。这有助于进步客户的购物体会和便利办理订单。

10. Flask-RESTful 自界说回来 JSON

有时,你或许需求自界说 API 回来的 JSON 格局,以满意特定的客户端需求或规范。你能够经过界说一个自界说的 JSON 编码器来完结这一点。

自界说 JSON 编码器:

你能够创立一个自界说的 JSON 编码器,承继自 flask.json.JSONEncoder 类,并重写 default 办法来界说怎么编码你的数据。

pythonCopy codefrom flask import Flask, jsonify
from flask.json import JSONEncoder
app = Flask(__name__)
# 自界说 JSON 编码器
class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, MyCustomObject):
            # 将 MyCustomObject 转换为字典
            return {'custom_data': obj.data}
        return super(CustomJSONEncoder, self).default(obj)
app.json_encoder = CustomJSONEncoder
class MyCustomObject:
    def __init__(self, data):
        self.data = data
@app.route('/')
def index():
    custom_obj = MyCustomObject('Custom data here')
    return jsonify(custom_obj)
if __name__ == '__main__':
    app.run()

在上面的示例中,咱们创立了一个自界说 JSON 编码器 CustomJSONEncoder,并在 default 办法中指定了怎么将自界说方针 MyCustomObject 编码为 JSON。然后,咱们将该编码器设置为 Flask 运用的默许 JSON 编码器。

商业事例:

假定你的运用中有一个用户办理体系,你期望用户数据在 API 中以特定格局回来,包含用户的名字、电子邮件和注册日期。你能够运用自界说 JSON 编码器来保证数据以所需的格局回来。

from flask import Flask, jsonify
from flask.json import JSONEncoder
from datetime import datetime
app = Flask(__name__)
# 自界说 JSON 编码器
class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, User):
            # 将 User 方针转换为所需的 JSON 格局
            return {'name': obj.name, 'email': obj.email, 'registration_date': obj.registration_date.strftime('%Y-%m-%d')}
        return super(CustomJSONEncoder, self).default(obj)
app.json_encoder = CustomJSONEncoder
class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email
        self.registration_date = datetime.now()
@app.route('/')
def get_user():
    user = User('John Doe', 'john@example.com')
    return jsonify(user)
if __name__ == '__main__':
    app.run()

在这个示例中,User 类代表用户方针,咱们运用自界说 JSON 编码器来保证用户数据以所需的格局回来。这样,API 将回来用户的名字、电子邮件和注册日期,而不是默许的方针表明办法。这有助于保证 API 的呼应数据满意客户端的特定需求。你能够运用装修器来自界说 Flask-RESTful API 的回来 JSON 格局。在 Flask-RESTful 中,能够经过自界说装修器来处理呼应数据的格局化和包装。以下是一个示例,展现怎么运用装修器自界说回来 JSON 格局:

from flask import Flask, jsonify, request
from functools import wraps
app = Flask(__name__)
# 自界说装修器,用于将函数回来的数据包装成 JSON 格局
def json_response(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        response = jsonify(result)
        return response
    return wrapper
# 运用装修器到路由函数
@app.route('/user')
@json_response
def get_user():
    user_data = {
        'name': 'John Doe',
        'email': 'john@example.com',
        'age': 30
    }
    return user_data
@app.route('/product')
@json_response
def get_product():
    product_data = {
        'name': 'Product A',
        'price': 50.0,
        'description': 'A great product'
    }
    return product_data
if __name__ == '__main__':
    app.run()

在上述示例中,咱们界说了一个自界说装修器 json_response,它承受一个函数作为参数,并回来一个新的函数 wrapperwrapper 函数担任调用原始函数并将其回来值包装成 JSON 格局的呼应。

然后,咱们运用了 json_response 装修器到两个路由函数 get_userget_product。当客户端拜访这些路由时,这些函数将回来字典办法的数据,并由装修器包装成 JSON 格局的呼应。

这种办法答应你轻松地在不同的路由函数中运用相同的格局化逻辑,以保证 API 的呼应数据都以共同的 JSON 格局回来给客户端。这关于坚持代码的共同性和可保护性十分有协助。

Flask-RESTful 自界说输出函数来自界说回来 JSON

from flask import Flask, jsonify, request
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
# 自界说输出函数,用于生成自界说的 JSON 格局呼应数据
def custom_output(data, code, headers=None):
    # 在这儿自界说生成 JSON 数据的逻辑
    if code == 200:
        result = {'status': 'success', 'data': data}
    else:
        result = {'status': 'error', 'message': data}
    resp = jsonify(result)
    resp.status_code = code
    if headers:
        resp.headers.extend(headers)
    return resp
# 设置自界说输出函数为 JSON 表明办法
api.representation(mediatype="application/json")(custom_output)
# 模仿待办事项数据
todos = {
    1: {'task': 'Buy groceries', 'done': False},
    2: {'task': 'Read a book', 'done': False},
}
# 创立待办事项资源
class TodoResource(Resource):
    def get(self, todo_id):
        if todo_id in todos:
            return todos[todo_id], 200
        else:
            return 'Todo not found', 404
    def put(self, todo_id):
        data = request.get_json()
        if todo_id not in todos:
            return 'Todo not found', 404
        if 'task' in data:
            todos[todo_id]['task'] = data['task']
        if 'done' in data:
            todos[todo_id]['done'] = data['done']
        return todos[todo_id], 200
    def delete(self, todo_id):
        if todo_id in todos:
            del todos[todo_id]
            return 'Todo deleted', 204
        else:
            return 'Todo not found', 404
# 增加待办事项资源到 API
api.add_resource(TodoResource, '/todos/<int:todo_id>')
if __name__ == '__main__':
    app.run()

在这个事例中,咱们创立了一个简略的待办事项 API,运用自界说输出函数 custom_output 来操控呼应的 JSON 格局。这个自界说输出函数依据呼应的状况码和数据生成不同的 JSON 结构,以满意客户端的需求。

API 具有以下功用:

  • GET /todos/:获取指定 ID 的待办事项。
  • PUT /todos/:更新指定 ID 的待办事项的使命和完结状况。
  • DELETE /todos/:删去指定 ID 的待办事项。

当客户端宣布这些恳求时,API 运用自界说输出函数生成 JSON 格局的呼应,以供给有关待办事项的信息。

这个示例展现了怎么运用自界说输出函数来灵敏地构建自界说 JSON 呼应格局,以习惯不同的 API 需求。

11.Flask-SQLAlchemy

11.1 根本介绍

Flask-SQLAlchemy 是一个用于在 Flask 运用中操作 SQL 数据库的扩展,它简化了数据库衔接、模型界说和数据操作的进程。下面我将介绍 Flask-SQLAlchemy 的特色、优缺点以及适用场景。

特色:
  1. 集成性: Flask-SQLAlchemy 与 Flask 结构无缝集成,易于与 Flask 运用一起运用。
  2. ORM 支撑: 它依据 SQLAlchemy 构建,供给了方针联系映射(ORM)功用,答应你运用 Python 类来表明数据库表格,并进行方针化的数据操作。
  3. 数据库支撑: Flask-SQLAlchemy 支撑多种数据库后端,包含 SQLite、MySQL、PostgreSQL 等。
  4. 数据库搬迁支撑: 集成了 Alembic,能够便利地进行数据库搬迁办理,处理模型的改变。
  5. 业务办理: 支撑业务,保证数据库操作的原子性,答应回滚到之前的状况。
  6. 查询构建器: 供给了强壮的查询构建器,运用链式办法构建杂乱的数据库查询。
  7. 功用优化: Flask-SQLAlchemy 具有功用优化功用,如缓存查询成果、推迟加载等。
长处:
  1. 易用性: Flask-SQLAlchemy 简化了数据库操作的进程,使开发人员能够专注于业务逻辑而不用处理杂乱的 SQL 查询。
  2. ORM 支撑: 供给了 ORM 功用,使数据模型与数据库表格的映射愈加直观和易于保护。
  3. 集成性: 与 Flask 集成杰出,无需额定的装备,易于上手。
  4. 数据库搬迁: 集成了 Alembic,能够轻松地办理数据库模型的改变,保证数据库的演化与运用程序共同。
  5. 可扩展性: 支撑多种数据库后端,适用于各种不同的项目需求。
缺点:
  1. 学习曲线: 关于新手来说,或许需求一些时刻来了解 SQLAlchemy 和 Flask-SQLAlchemy 的概念。
  2. 灵敏性: Flask-SQLAlchemy 依据 SQLAlchemy 构建,关于某些需求更高度自界说 SQL 查询的场景,或许需求额定的尽力。
运用场景:

Flask-SQLAlchemy 适用于各种不同类型的运用,特别是那些需求与 SQL 数据库交互的运用。以下是一些合适运用 Flask-SQLAlchemy 的场景:

  1. Web 运用程序: 无论是小型博客、电子商务网站仍是大型社交媒体平台,Flask-SQLAlchemy 都能够用于办理用户数据、文章、评论等。
  2. 后端服务: 假如你的运用需求供给 API 服务或微服务,Flask-SQLAlchemy 能够用于办理和存储数据。
  3. 办理面板: 后台办理面板一般需求对数据库进行 CRUD 操作,Flask-SQLAlchemy 能够简化办理面板的开发。
  4. 数据剖析东西: 假如你需求构建数据剖析东西或仪表板,Flask-SQLAlchemy 能够与数据存储集成,协助你查询和剖析数据。

总归,Flask-SQLAlchemy 是一个强壮而灵敏的东西,适用于许多不同类型的运用程序。它的集成性、ORM 支撑和数据库搬迁功用使其成为构建可保护、可扩展和高功用的运用程序的有力东西。但是,在挑选运用 Flask-SQLAlchemy 之前,你应该考虑你的项目需求和团队的熟练程度,以确定它是否合适你的特定状况。

11.2 Flask-SQLAlchemy 环境装置

要装置 Flask-SQLAlchemy 环境,你需求先装置 Flask 和 SQLAlchemy,然后再装置 Flask-SQLAlchemy 扩展。下面是具体的装置进程:

进程 1:创立虚拟环境(可选但引荐)

虚拟环境可用于阻隔项目的依靠,以防止与其他项目抵触。能够运用 Python 的 venv 模块来创立虚拟环境。

首要,进入你的项目目录,然后运转以下指令创立虚拟环境:

python -m venv venv

接下来,激活虚拟环境:

  • 在 macOS 和 Linux 上:

    source venv/bin/activate
    
  • 在 Windows 上:

    venv\Scripts\activate
    
进程 2:装置 Flask

在虚拟环境中激活后,能够运用 pip 装置 Flask:

pip install Flask
进程 3:装置 SQLAlchemy

装置 SQLAlchemy,Flask-SQLAlchemy 依靠于 SQLAlchemy:

pip install SQLAlchemy
进程 4:装置 Flask-SQLAlchemy

装置 Flask-SQLAlchemy 扩展:

pip install Flask-SQLAlchemy
进程 5:创立 Flask 运用

创立一个 Flask 运用,并装备数据库衔接 URI。一般,你需求将以下代码增加到你的 Flask 运用中:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
​
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
db = SQLAlchemy(app)
  • SQLALCHEMY_DATABASE_URI 装备项用于指定数据库的衔接 URI。上述示例运用 SQLite 数据库,数据库文件为 mydatabase.db,你能够依据需求更改为其他数据库。
进程 6:界说模型(可选)

假如你计划在运用中运用数据库模型(ORM),则需求界说模型类,表明数据库中的表格和字段。例如:

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    def __repr__(self):
        return f'<User {self.username}>'
进程 7:创立数据库和表格(可选)

假如你现已界说了模型类,能够运用 Flask-SQLAlchemy 来创立数据库和表格。在虚拟环境中运转以下指令:

python

然后在 Python REPL 中履行:

from your_app import db
with app.app_context():
    db.create_all()

这将创立数据库和模型界说的表格。你能够退出 Python REPL。

现在,你的 Flask-SQLAlchemy 环境现已装置和装备完结,你能够开端开发运用程序并与数据库进行交互了。保证在代码中正确运用 Flask-SQLAlchemy 供给的功用来进行数据库操作和查询。

11.3 Flask-SQLAlchemy 扩展根本装备

Flask-SQLAlchemy 的根本装备首要是装备与数据库衔接相关的参数。以下是 Flask-SQLAlchemy 的根本装备参数及其阐明:

  1. SQLALCHEMY_DATABASE_URI:指定数据库的衔接 URI。这是一个必需的装备项,它告知 Flask-SQLAlchemy 运用衔接哪个数据库。衔接 URI 的格局取决于你运用的数据库类型,例如:

    • SQLite 数据库衔接 URI:sqlite:///mydatabase.db
    • MySQL 数据库衔接 URI:mysql://username:password@hostname/database
    • PostgreSQL 数据库衔接 URI:postgresql://username:password@hostname/database
  2. SQLALCHEMY_BINDS:用于多数据库衔接时的绑定装备。能够装备多个数据库衔接,每个衔接都有一个键和对应的衔接 URI。例如:

    pythonCopy codeapp.config['SQLALCHEMY_BINDS'] = {
        'db1': 'sqlite:///db1.db',
        'db2': 'postgresql://user:password@localhost/db2'
    }
    

    这答应你在运用中运用多个数据库衔接。

  3. SQLALCHEMY_ECHO:设置为 True 时,将打印 SQL 句子和查询到的数据,用于调试和日志记载。默许为 False

  4. SQLALCHEMY_POOL_SIZE:数据库衔接池中衔接的数量。默许为 5。

  5. SQLALCHEMY_POOL_TIMEOUT:衔接池中的衔接超时时刻(以秒为单位)。默许为 10。

  6. SQLALCHEMY_POOL_RECYCLE:衔接池中的衔接在被收回之前的秒数。默许为 -1(不收回)。

  7. SQLALCHEMY_MAX_OVERFLOW:衔接池中能够创立的最大衔接数。默许为 None(不约束)。

  8. SQLALCHEMY_TRACK_MODIFICATIONS:用于追寻方针的修正并宣布警告。在出产环境中应设置为 False,以进步功用。默许为 True

  9. SQLALCHEMY_COMMIT_ON_TEARDOWN:设置为 True 时,在恳求完毕后主动提交业务。默许为 False

  10. SQLALCHEMY_NATIVE_UNICODE:设置为 True 时,启用数据库驱动的原生 Unicode 支撑。默许为 False

  11. SQLALCHEMY_RECORD_QUERIES:设置为 True 时,启用查询记载。默许为 None

  12. SQLALCHEMY_ENGINE_OPTIONS:用于传递额定的数据库引擎选项的字典。例如:

    pythonCopy codeapp.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
        'pool_size': 10,
        'max_overflow': 20
    }
    

这些装备参数能够经过在 Flask 运用中设置 app.config 来进行装备。例如:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

在上述示例中,咱们装备了数据库衔接 URI 为 SQLite 数据库,并禁用了 SQLAlchemy 的修正盯梢功用。

你能够依据你的运用需求来装备这些参数。请注意,不同的数据库类型和环境或许需求不同的装备参数。依据你的数据库挑选和布置环境,适当地装备这些参数以保证运用的功用和稳定性。

11.4 创立数据库方针[拖延相关app]

在 Flask-SQLAlchemy 中,你能够先创立数据库方针,然后在稍后相关到 Flask 运用中。这一般是在运用工厂函数或在需求推迟初始化的地方履行的。下面是一个示例,演示怎么创立数据库方针并拖延相关到 Flask 运用:

from flask_sqlalchemy import SQLAlchemy
# 创立数据库方针,但不相关到 Flask 运用
db = SQLAlchemy()
# 创立 Flask 运用的工厂函数
def create_app():
    app = Flask(__name__)
    # 装备数据库衔接 URI
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
    # 装备其他数据库参数(可选)
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    # 将数据库方针相关到 Flask 运用
    db.init_app(app)
    # 在这儿能够持续装备其他 Flask 扩展或路由
    return app
# 创立运用并运转
if __name__ == '__main__':
    app = create_app()
    app.run()

在上述示例中,咱们首要创立了一个名为 db 的 SQLAlchemy 数据库方针,但没有当即相关到 Flask 运用。然后,咱们创立了一个运用工厂函数 create_app(),在其间装备运用和数据库衔接。最终,咱们运用 db.init_app(app) 来将数据库方针相关到运用。

这种推迟相关的办法答应你在不同的运用装备中重复运用数据库方针,以及更好地安排和办理你的运用代码。当运用运转时,数据库方针会在需求时进行初始化。这是一种常见的做法,特别是在大型运用中,以保证运用的结构和可保护性。

11.5 Flask-SQLAlchemy界说模型

在 Flask-SQLAlchemy 中,你能够经过界说模型类来表明数据库表格和字段。每个模型类对应一个数据库表格,类的特色对应表格的字段。下面具体解说怎么在 Flask-SQLAlchemy 中界说模型类,并供给一个实践的商业事例。

进程 1:导入 Flask 和 Flask-SQLAlchemy

首要,你需求导入 Flask 和 Flask-SQLAlchemy 扩展:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
进程 2:创立 Flask 运用和装备数据库衔接

创立一个 Flask 运用并装备数据库衔接 URI,以及其他数据库相关的装备。一般,你能够在 Flask 运用工厂函数中进行这些装备,如下所示:

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'  # 设置数据库衔接 URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # 制止修正盯梢功用
db = SQLAlchemy(app)  # 创立 Flask-SQLAlchemy 方针并相关到运用
进程 3:界说模型类

运用 Flask-SQLAlchemy 界说模型类,每个模型类对应一个数据库表格。例如,假定你要创立一个用户表格:

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    def __repr__(self):
        return f'<User {self.username}>'

在上面的示例中:

  • db.Model 是 Flask-SQLAlchemy 供给的基类,一切模型类都应该承继自它。
  • idusernameemail 是表格的字段,经过 db.Column 界说。你能够指定字段的数据类型、仅有性、是否答应为空等特色。
商业事例:

假定你正在开发一个电子商务网站,需求存储用户信息。你能够运用 Flask-SQLAlchemy 来创立一个 User 模型类来表明用户,其间 id 字段用于仅有标识用户,username 字段存储用户名,email 字段存储电子邮件地址。

这个 User 模型类将答应你在数据库中创立一个用户表格,用于存储用户的信息。你能够运用模型类的办法来创立、查询、更新和删去用户记载,以及履行与用户相关的数据库操作。例如,你能够创立新用户记载:

enew_user = User(username='john_doe', email='john@example.com')
db.session.add(new_user)
db.session.commit()

经过界说模型类,你能够在运用中轻松地办理和操作数据库表格,运用户数据的存储和检索变得十分便利。这是一个实践运用中常见的用例,触及用户信息的存储和办理。

11.6 Flask-SQLAlchemy 操作数据

1. 数据操作根底

在运用 Flask-SQLAlchemy 进行数据操作之前,你需求首要导入 Flask、Flask-SQLAlchemy 和相关的模型类。假定你现已界说了一个 User 模型类来表明用户,下面是一些根本的数据操作示例:

刺进数据:
# 创立新用户并增加到数据库
new_user = User(username='john_doe', email='john@example.com')
db.session.add(new_user)
db.session.commit()

在上述示例中,咱们首要创立了一个新的 User 实例,然后运用 db.session.add() 办法将它增加到数据库会话中,最终经过 db.session.commit() 提交业务,将新用户记载刺进到数据库中。

查询数据:
# 查询一切用户
all_users = User.query.all()
# 依据条件查询用户
user = User.query.filter_by(username='john_doe').first()

你能够运用 query 特色来构建查询,例如 User.query,然后运用链式办法来增加条件和排序。在上述示例中,咱们查询了一切用户和依据用户名查询用户。

更新数据:
# 查询要更新的用户
user = User.query.filter_by(username='john_doe').first()
​
# 更新用户信息
user.email = 'new_email@example.com'
db.session.commit()

首要,咱们查询了要更新的用户,然后修正了用户的特色值,最终提交业务以保存更改。

删去数据:

# 查询要删去的用户
user = User.query.filter_by(username='john_doe').first()
​
# 删去用户
db.session.delete(user)
db.session.commit()

咱们首要查询要删去的用户,然后运用 db.session.delete() 办法删去用户记载,并经过 db.session.commit() 提交业务,从数据库中删去用户。

2. 商业事例

假定你正在开发一个在线商城网站,你能够运用 Flask-SQLAlchemy 来履行各种数据操作,以办理产品、订单和用户等数据。以下是一个商业事例,阐明怎么在这个场景下运用 Flask-SQLAlchemy 进行数据操作:

创立订单:

当用户在你的网站上购买产品时,你能够运用 Flask-SQLAlchemy 来创立订单记载,将订单信息存储到数据库中:

from models import Order  # 导入订单模型类
​
# 创立订单
new_order = Order(user_id=1, product_id=101, quantity=2, total_price=50.0)
db.session.add(new_order)
db.session.commit()
查询用户订单:

用户能够登录并检查他们的订单历史。你能够运用 Flask-SQLAlchemy 查询来检索用户的订单记载:

from models import Order  # 导入订单模型类# 查询特定用户的订单
user_orders = Order.query.filter_by(user_id=1).all()
更新订单状况:

当订单发货或交给时,你能够运用 Flask-SQLAlchemy 更新订单的状况:

from models import Order  # 导入订单模型类# 查询要更新状况的订单
order = Order.query.filter_by(order_id=1001).first()
​
# 更新订单状况
order.status = '已发货'
db.session.commit()
删去订单:

假如需求撤销订单,你能够运用 Flask-SQLAlchemy 删去订单记载:

from models import Order  # 导入订单模型类
​
# 查询要撤销的订单
order = Order.query.filter_by(order_id=1001).first()
​
# 删去订单
db.session.delete(order)
db.session.commit()

在这个商业事例中,Flask-SQLAlchemy 被用来办理订单数据,包含创立订单、查询用户订单、更新订单状况和删去订单。这些数据操作是在线商城网站的要害功用,Flask-SQLAlchemy 能够便利地支撑这些操作,并保证订单数据的共同性和可靠性。

11.7 Flask-SQLAlchemy 高档查询

1. 过滤数据
  • 查询特定条件的记载

你能够运用 filter()filter_by() 办法来查询契合特定条件的记载。例如,假定你有一个 Product 模型,想要查询价格大于 50 的产品:

from models import Product  # 导入产品模型类# 查询价格大于 50 的产品
expensive_products = Product.query.filter(Product.price > 50).all()
  • 查询多个条件的记载

你能够运用 filter() 办法来组合多个条件,例如一起满意价格大于 50 而且库存大于 0 的产品:

from models import Product  # 导入产品模型类# 查询价格大于 50 而且库存大于 0 的产品
products = Product.query.filter((Product.price > 50) & (Product.stock > 0)).all()
2. 排序数据
  • 单一字段排序

运用 order_by() 办法依照单一字段对查询成果进行排序。例如,按价格降序排序产品:

from models import Product  # 导入产品模型类# 按价格降序排序产品
sorted_products = Product.query.order_by(Product.price.desc()).all()
  • 多字段排序

你还能够按多个字段排序。例如,按价格降序排序产品,假如价格相同则按称号升序排序:

from models import Product  # 导入产品模型类# 按价格降序排序产品,假如价格相同则按称号升序排序
sorted_products = Product.query.order_by(Product.price.desc(), Product.name).all()
3.分页数据

关于大型数据集,你能够运用 paginate() 办法来分页检索数据。该办法承受两个参数:页码和每页的记载数。例如,获取第二页的产品,每页显现 10 条记载:

from models import Product  # 导入产品模型类# 获取第二页的产品,每页显现 10 条记载
page = 2
per_page = 10
products = Product.query.paginate(page, per_page, False)
4. 聚合函数

聚合函数答应你履行诸如计数、求和、平均值等核算操作。例如,核算产品的平均价格:

pythonCopy codefrom models import Product  # 导入产品模型类
from sqlalchemy import func
​
# 核算产品的平均价格
avg_price = db.session.query(func.avg(Product.price)).scalar()
商业事例

假定你正在开发一个电子商务平台,需求依据用户的需求来检索产品数据。以下是一个商业事例,演示怎么运用 Flask-SQLAlchemy 的高档查询功用:

  • 依据用户需求检索产品

用户能够在平台上依据不同的条件来查找产品,包含价格规模、品牌、类别等。你能够运用 Flask-SQLAlchemy 来构建灵敏的查询,以满意用户的需求:

from models import Product  # 导入产品模型类# 用户挑选的条件
min_price = 20
max_price = 50
selected_brand = 'Brand X'
selected_category = 'Electronics'# 构建查询
query = Product.query
​
# 依据价格规模过滤
query = query.filter((Product.price >= min_price) & (Product.price <= max_price))
​
# 依据品牌过滤
query = query.filter_by(brand=selected_brand)
​
# 依据类别过滤
query = query.filter_by(category=selected_category)
​
# 按价格升序排序
query = query.order_by(Product.price.asc())
​
# 获取分页数据
page = 1
per_page = 10
products = query.paginate(page, per_page, False)

在这个商业事例中,咱们依据用户挑选的条件构建了一个动态的查询,然后按价格升序排序产品,并运用分页功用来显现成果。这样的高档查询功用能够运用户更轻松地查找和购买他们感兴趣的产品。

11.8 Flask-SQLAlchemy 数据改写

Flask-SQLAlchemy 是 Flask 的扩展之一,用于与 SQL 数据库进行交互。其间之一的数据改写(Data Refresh)指的是在数据库中更新数据的操作。在运用 Flask-SQLAlchemy 进行数据改写时,一般会触及查询现有数据、修正数据,然后将更改保存回数据库。以下是关于数据改写的具体解说和一个商业事例:

数据改写的流程:

数据改写一般包含以下几个进程:

  1. 查询数据:首要,您需求查询数据库以获取需求更新的数据。这能够经过 SQLAlchemy 的查询接口来完结。
  2. 修正数据:一旦获取了数据,您能够对其进行修正。这能够包含更新字段、增加新数据或删去数据,具体取决于您的需求。
  3. 保存更改:最终,您需求将修正后的数据保存回数据库,以保证更改收效。

以下是一个示例:

pythonCopy codefrom flask_sqlalchemy import SQLAlchemy
​
# 进程1:查询数据
item = Item.query.get(item_id)
​
if item:
   # 进程2:修正数据
   item.name = 'New Name'
   item.price = 19.99# 进程3:保存更改
   db.session.commit()

在上面的示例中,咱们首要查询了一个名为 Item 的数据模型(Model)中的特定项目,然后对项目的特色进行了修正,最终经过 db.session.commit() 将更改保存到数据库中。

商业事例:

假定您正在开发一个在线商铺的电子商务平台。以下是一个商业事例示例,展现了怎么运用 Flask-SQLAlchemy 进行数据改写。

场景

您的在线商铺具有产品办理功用,您需求定时更新产品信息,例如价格、库存等。

解决方案

  1. 查询产品信息:首要,运用 Flask-SQLAlchemy 查询现有产品的信息。例如,您能够查询某个特定产品的价格和库存。
product = Product.query.get(product_id)
  1. 修正产品信息:接下来,依据您的需求修正产品信息。例如,您能够将产品的价格调整为新的销售价格,并削减库存数量。
if product:
   product.price = 14.99
   product.stock -= 1
  1. 保存更改:最终,运用 db.session.commit() 将产品信息的更改保存回数据库中。
if product:
   db.session.commit()

这个商业事例中,Flask-SQLAlchemy 协助您轻松办理产品信息的更新。经过履行数据改写操作,您能够保证产品信息始终坚持最新,然后进步在线商铺的功率和用户体会。此外,您能够将此进程主动化,例如经过定时使命来定时更新产品信息,以保证价格、库存等信息与供应商的数据坚持同步。

flush

在 Flask-SQLAlchemy 中,flush 是 SQLAlchemy 中的一个操作,用于将未提交的更改改写到数据库中。具体来说,flush 将一切挂起的 INSERT、UPDATE、DELETE 操作发送到数据库,但不提交业务。这答应您在不提交更改的状况下检查它们是否正确,以便在需求时进行回滚或提交。

以下是关于 flush 操作的具体解说和商业事例:

flush 操作一般用于以下状况:

  1. 检查挂起的更改:您能够运用 flush 操作来检查将要运用到数据库的更改,以保证它们是正确的。
  2. 预检查业务:在提交业务之前,能够运用 flush 来进行预检查。假如发现任何问题,能够回滚业务而不是提交。
  • 商业事例:

假定您正在开发一个在线预定体系,您的体系答运用户预定酒店房间。以下是一个商业事例示例,展现了怎么运用 flush 操作。

场景

您的在线预定体系答运用户预定酒店房间。用户能够挑选日期、房型和付款办法进行预定。在提交预定之前,您需求保证用户供给的信息是有用的,而且房间依然可用。

解决方案

  1. 创立预定方针:首要,创立一个预定方针并将用户供给的信息存储在方针中。
pythonCopy codefrom your_app.models import Reservation
​
reservation = Reservation(
   user_id=user_id,
   room_type=selected_room_type,
   check_in_date=check_in_date,
   check_out_date=check_out_date,
   payment_method=selected_payment_method,
)
  1. 验证信息:在提交预定之前,运用 flush 来验证用户供给的信息是否有用。检查用户所选的房间类型是否可用,并验证付款办法是否有用。
pythonCopy codeif is_room_available(selected_room_type) and is_valid_payment(selected_payment_method):
   # 假如信息有用,履行flush
   db.session.add(reservation)
   db.session.flush()
else:
   # 假如信息无效,回滚业务
   db.session.rollback()
  1. 提交或回滚业务:依据前面的验证成果,您能够决议是提交业务仍是回滚业务。
if reservation.id:
   # 提交业务
   db.session.commit()
else:
   # 回滚业务
   db.session.rollback()

在这个商业事例中,flush 操作用于在提交预定之前进行信息验证。假如信息有用,业务将提交,用户的预定将被确认。假如信息无效,业务将被回滚,预定将被撤销。这有助于保证用户供给的信息是正确的,而且酒店房间的可用性不会遭到无效的预定恳求的影响。

11.9 Flask-SQLAlchemy 相关查询

Flask-SQLAlchemy 支撑相关查询,这是一种强壮的功用,能够在多个表之间履行杂乱的查询操作,特别是在触及到多个数据库表之间的相相联系时。相关查询答应您在一个查询中检索多个表的数据,使您能够轻松地从相关的表中获取相关信息。

以下是关于 Flask-SQLAlchemy 相关查询的具体解说和示例:

  • 相关查询的类型:

在 Flask-SQLAlchemy 中,有几种类型的相关查询,包含:

  1. 一对多相关查询:一张表中的每一行相关到另一张表中的多行数据。例如,一个作者能够写多本书。
  2. 多对一相关查询:多张表中的多行数据相关到另一张表中的一行数据。例如,多个订单能够相关到一个客户。
  3. 多对多相关查询:多张表中的多行数据相关到另一张表中的多行数据。例如,多个学生能够参与多个课程。
  • 示例:

让咱们以一个简略的示例来阐明相关查询。假定您正在开发一个博客运用,其间有两个表:UserPost,它们之间存在一对多的相相联系,一个用户能够发布多篇文章。

首要,您需求界说模型(Model):

from flask_sqlalchemy import SQLAlchemy
​
db = SQLAlchemy()
​
class User(db.Model):
   id = db.Column(db.Integer, primary_key=True)
   username = db.Column(db.String(80), unique=True, nullable=False)
   posts = db.relationship('Post', backref='author', lazy=True)
​
class Post(db.Model):
   id = db.Column(db.Integer, primary_key=True)
   title = db.Column(db.String(120), nullable=False)
   content = db.Column(db.Text, nullable=False)
   user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

在上述代码中,User 模型和 Post 模型之间建立了一对多的联系,User 模型经过 posts 特色与 Post 模型相关。

现在,您能够履行相关查询来获取用户及其发布的文章。以下是一个示例:

# 查询用户及其发布的文章
user = User.query.filter_by(username='john').first()
if user:
   posts = user.posts.all()
   for post in posts:
     print(f"Title: {post.title}, Content: {post.content}")

在这个示例中,首要查询了一个特定用户名的用户方针,然后经过 user.posts.all() 获取该用户发布的一切文章。

这是一个简略的相关查询示例,您能够依据运用程序的需求履行更杂乱的相关查询,以获取相关数据。相关查询是在多表联系中查询和检索数据时的有力东西,使您能够轻松地拜访相关表中的信息。

  • join衔接查询详解

    在联系型数据库中,JOIN 是一种用于在多个表之间进行相关查询的操作。JOIN 答应您将多个表的数据组合在一起,以便在一个查询中获取来自不同表的相关信息。在 Flask-SQLAlchemy 中,您能够运用 SQLAlchemy 供给的 join 办法来履行衔接查询。

    以下是关于衔接查询的具体解说和示例:

    衔接查询的类型:

    在 SQLAlchemy 中,有几种类型的衔接查询,包含:

    1. INNER JOIN:内衔接,回来两个表中匹配行的交集。只回来两个表中共有的数据。
    2. LEFT JOIN(或称为 LEFT OUTER JOIN):左衔接,回来左表中的一切行,以及右表中与左表匹配的行。假如右表中没有匹配的行,将回来 NULL 值。
    3. RIGHT JOIN(或称为 RIGHT OUTER JOIN):右衔接,与左衔接相反,回来右表中的一切行,以及左表中与右表匹配的行。假如左表中没有匹配的行,将回来 NULL 值。
    4. FULL OUTER JOIN:全外衔接,回来两个表中的一切行,假如某个表中没有匹配的行,将回来 NULL 值。

    示例:

    让咱们运用一个示例来阐明衔接查询。假定您有两个表:OrderProduct,它们之间有一对多的联系,一个订单能够包含多个产品。咱们将履行一个衔接查询来获取订单及其包含的产品信息。

    首要,界说数据库模型(Model):

    from flask_sqlalchemy import SQLAlchemy
    ​
    db = SQLAlchemy()
    ​
    # 订单模型
    class Order(db.Model):
       id = db.Column(db.Integer, primary_key=True)
       order_number = db.Column(db.String(20), nullable=False, unique=True)
       products = db.relationship('Product', backref='order', lazy=True)
    ​
    # 产品模型
    class Product(db.Model):
       id = db.Column(db.Integer, primary_key=True)
       name = db.Column(db.String(100), nullable=False)
       price = db.Column(db.Float, nullable=False)
       order_id = db.Column(db.Integer, db.ForeignKey('order.id'), nullable=False)
    

    然后,履行衔接查询:

    from sqlalchemy.orm import joinedload
    ​
    # 内衔接查询
    orders_with_products = db.session.query(Order, Product).join(Product, Order.id == Product.order_id).all()
    ​
    # 运用 joinedload 进行慵懒加载
    orders_with_products_lazy = db.session.query(Order).options(joinedload(Order.products)).all()
    ​
    # 打印成果
    for order, product in orders_with_products:
       print(f"Order Number: {order.order_number}, Product: {product.name}, Price: {product.price}")
    ​
    # 或许运用慵懒加载的查询成果
    for order in orders_with_products_lazy:
       print(f"Order Number: {order.order_number}, Products: {[product.name for product in order.products]}")
    

    在上述代码中,咱们首要界说了 OrderProduct 两个模型,建立了它们之间的一对多联系。然后,咱们运用衔接查询获取订单及其包含的产品信息。在内衔接查询中,咱们运用 join 办法将两个表衔接在一起,经过 Order.id == Product.order_id 条件指定衔接条件。衔接查询的成果将包含订单和产品的相关信息。

    另外,咱们还运用了 joinedload 办法进行慵懒加载,以防止 N+1 查询问题。这答应咱们在一次查询中获取一切订单和产品的信息。

    这个示例演示了怎么履行衔接查询,以获取多个表之间的相关数据。衔接查询是在处理杂乱数据联系时的有用东西,能够协助您高效地检索和剖析数据。

12.0 SQLAlchemy数据库搬迁

SQLAlchemy 是一个强壮的 Python ORM(Object-Relational Mapping)库,用于与联系型数据库进行交互。数据库搬迁是在开发中常见的使命之一,它答应您在数据库模型产生改变时坚持数据库的结构和数据的共同性。在 SQLAlchemy 中,一般运用第三方扩展如 Flask-Migrate 来办理数据库搬迁。

以下是关于 SQLAlchemy 数据库搬迁的具体解说和商业事例:

  • 数据库搬迁的进程:

数据库搬迁一般包含以下几个进程:

  1. 界说数据库模型:首要,您需求界说数据库模型,这些模型对应于数据库中的表格。您能够运用 SQLAlchemy 的模型类来界说表格结构和联系。
  2. 生成初始搬迁文件:运用数据库搬迁东西,如 Flask-Migrate,来生成初始搬迁文件。这个文件包含了当时数据库模型的状况信息。
  3. 修改搬迁文件:依据需求,修改搬迁文件以增加、修正或删去数据库模型。这些修改或许包含表格结构的更改、外键的增加或删去等。
  4. 运用搬迁:运用数据库搬迁东西来运用搬迁文件,将数据库模型的更改运用到实践数据库中。
  5. 搬迁回滚(可选):假如需求回滚更改,您能够运用数据库搬迁东西来履行回滚操作,将数据库恢复到之前的状况。
  • 商业事例:

假定您正在开发一个电子商务平台,您的运用程序有一个 Product 模型来表明产品。随着时刻的推移,您决议对 Product 模型进行一些更改,例如增加新的特色。

以下是一个示例商业事例,展现了怎么运用数据库搬迁来办理这些更改:

场景

您的电子商务平台有一个 Product 模型,用于存储产品信息。最初,Product 模型只包含 nameprice 两个特色。现在,您决议增加一个新的特色 description 来存储产品描述。

解决方案

  1. 生成初始搬迁文件:首要,运用数据库搬迁东西(例如 Flask-Migrate)生成初始搬迁文件,该文件反映当时的数据库模型状况。

  2. 修改搬迁文件:修改生成的搬迁文件以增加 description 字段到 Product 模型:

    def upgrade():
       op.add_column('product', sa.Column('description', sa.String(length=255), nullable=True))
    ​
    def downgrade():
       op.drop_column('product', 'description')
    
  3. 运用搬迁:运用数据库搬迁东西来运用搬迁文件,以将更改运用到实践数据库中。

    flask db upgrade
    
  4. 更新运用程序代码:在您的运用程序代码中,更新 Product 模型的界说以包含新的 description 字段。

    class Product(db.Model):
       id = db.Column(db.Integer, primary_key=True)
       name = db.Column(db.String(100), nullable=False)
       price = db.Column(db.Float, nullable=False)
       description = db.Column(db.String(255), nullable=True)  # 新增字段
    
  5. 更新运用程序逻辑:依据需求,更新运用程序的逻辑以运用新的 description 字段。例如,您能够在产品概况页面显现产品描述。

这个商业事例示例演示了怎么运用数据库搬迁来办理数据库模型的更改。数据库搬迁东西能够保证您的数据库结构与运用程序代码坚持同步,然后使您能够安全地进行数据库模型的演化。这关于开发长期保护的运用程序十分重要,由于它答应您在不丢失数据的状况下进行数据库模型的更新。