整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Flask WTF

Flask WTF

eb应用程序的一个重要方面是为用户提供一个用户界面。 HTML提供了一个<form>标签,用于设计一个接口。 可以适当使用表单的元素,如文本输入,广播,选择等。

通过GET或POST方法将用户输入的数据以Http请求消息的形式提交给服务器端脚本。

服务器端脚本必须从http请求数据重新创建表单元素。 所以实际上,表单元素必须被定义两次 - 一次是HTML,一次是服务器端脚本。使用HTML表单的另一个缺点是很难(如果不是不可能)动态地呈现表单元素。 HTML本身无法验证用户的输入。

这就是WTForms,一个灵活的表单,渲染和验证库来得方便的地方。 Flask-WTF扩展为这个WTForms库提供了一个简单的接口。

使用Flask-WTF,可以在Python脚本中定义表单域并使用HTML模板来呈现它们。 也可以将验证应用于WTF字段。

下面让我们看看这个动态生成HTML是如何工作的。

首先,需要安装Flask-WTF扩展。

# Filename : example.py
# Copyright : 2020 By Nhooo
# Author by : www.cainiaojc.com
# Date : 2020-08-08
pip install flask-WTF

已安装的软件包包含一个Form类,该类必须用作用户定义表单的父级。WTforms包包含各种表单域的定义。下面列出了一些标准表单字段。

编号

标准表单字段

描述

1

TextField

表示<input type='text'> HTML表单元素

2

BooleanField

表示<input type='checkbox'> HTML表单元素

3

DecimalField

用小数显示数字的文本字段

4

IntegerField

用于显示整数的文本字段

5

RadioField

表示<input type='radio'>的HTML表单元素

6

SelectField

表示选择表单元素

7

TextAreaField

表示<testarea> html表单元素

8

PasswordField

表示<input type='password'> HTML表单元素

9

SubmitField

表示<input type='submit'>表单元素

例如,可以设计一个包含文本字段的表单,如下所示 -

示例

# Filename : example.py
# Copyright : 2020 By Nhooo
# Author by : www.cainiaojc.com
# Date : 2020-08-08
from flask_wtf import Form
 from wtforms import TextField
 class ContactForm(Form):
     name=TextField("Name Of Student")

除了name字段之外,还会自动创建一个CSRF令牌的隐藏字段。 这是为了防止跨站请求伪造攻击。

渲染时,这将产生一个等效的HTML脚本,如下所示。

# Filename : example.py
# Copyright : 2020 By Nhooo
# Author by : www.cainiaojc.com
# Date : 2020-08-08
<input id="csrf_token" name="csrf_token" type="hidden" />
 <label for="name">Name Of Student</label><br>
 <input id="name" name="name" type="text" value="" />

用户定义的表单类在Flask应用程序中使用,表单使用模板呈现。

示例

# Filename : example.py
# Copyright : 2020 By Nhooo
# Author by : www.cainiaojc.com
# Date : 2020-08-08
from flask import Flask, render_template
 from forms import ContactForm
 app=Flask(__name__)
 app.secret_key='development key'
 @app.route('/contact')
 def contact():
     form=ContactForm()
     return render_template('contact.html', form=form)
 if __name__=='__main__':
     app.run(debug=True)

WTForms包也包含验证器类,在验证表单域时非常有用。 以下列表显示了常用的验证器。

编号

验证器类

描述

1

DataRequired

检查输入栏是否为空

2

Email

检查字段中的文本是否遵循电子邮件ID约定

3

IPAddress

验证输入字段中的IP地址

4

Length

验证输入字段中字符串的长度是否在给定范围内

5

NumberRange

在给定范围内的输入字段中验证一个数字

6

URL

验证输入字段中输入的URL

将联系表单的name字段应用'DataRequired'验证规则。

# Filename : example.py
# Copyright : 2020 By Nhooo
# Author by : www.cainiaojc.com
# Date : 2020-08-08
name=TextField("Name Of Student",[validators.Required("Please enter your name.")])

表单对象的validate()函数验证表单数据,并在验证失败时抛出验证错误。 错误消息被发送到模板。 在HTML模板中,错误消息是动态呈现的。

# Filename : example.py
# Copyright : 2020 By Nhooo
# Author by : www.cainiaojc.com
# Date : 2020-08-08
{% for message in form.name.errors %}
    {{ message }}
 {% endfor %}

以下示例演示了上面给出的概念。联系人表单代码如下( forms.py)。

示例

# Filename : example.py
# Copyright : 2020 By Nhooo
# Author by : www.cainiaojc.com
# Date : 2020-08-08
from flask_wtf import Form
 from wtforms import TextField, IntegerField, TextAreaField, SubmitField, RadioField, SelectField
 from wtforms import validators, ValidationError
 class ContactForm(Form):
     name=TextField("学生姓名",[validators.Required("Please enter your name.")])
     Gender=RadioField('性别', choices=[('M','Male'),('F','Female')])
     Address=TextAreaField("地址")
     email=TextField("Email",[validators.Required("Please enter your email address."),
       validators.Email("Please enter your email address.")])
     Age=IntegerField("年龄")
     language=SelectField('语言', choices=[('cpp', 'C++'), ('py', 'Python')])
     submit=SubmitField("提交")

验证器应用于名称和电子邮件字段。下面给出的是Flask应用程序脚本( formexample.py)。

示例

# Filename : example.py
# Copyright : 2020 By Nhooo
# Author by : www.cainiaojc.com
# Date : 2020-08-08
from flask import Flask, render_template, request, flash
 from forms import ContactForm
 app=Flask(__name__)
 app.secret_key='development key'
 @app.route('/contact', methods=['GET', 'POST'])
 def contact():
     form=ContactForm()
     if request.method=='POST':
        if form.validate()==False:
           flash('All fields are required.')
           return render_template('contact.html', form=form)
        else:
           return render_template('success.html')
     elif request.method=='GET':
           return render_template('contact.html', form=form)
 if __name__=='__main__':
     app.run(debug=True)

模板的脚本( contact.html)如下所示 -

# Filename : example.py
# Copyright : 2020 By Nhooo
# Author by : www.cainiaojc.com
# Date : 2020-08-08
<html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>Flask示例</title>
 </head>
    <body>
      <h2 style="text-align: center;">联系人表单</h2>
       {% for message in form.name.errors %}
          <div>{{ message }}</div>
       {% endfor %}
       {% for message in form.email.errors %}
          <div>{{ message }}</div>
       {% endfor %}
       <form action="http://localhost:5000/contact" method=post>
          <fieldset>
             <legend>填写项</legend>
             {{ form.hidden_tag() }}
             <div style=font-size:20px; font-weight:bold; margin-left:150px;>
                {{ form.name.label }}<br>
                {{ form.name }}
                <br>
                {{ form.Gender.label }} {{ form.Gender }}
                {{ form.Address.label }}<br>
                {{ form.Address }}
                <br>
                {{ form.email.label }}<br>
                {{ form.email }}
                <br>
                {{ form.Age.label }}<br>
                {{ form.Age }}
                <br>
                {{ form.language.label }}<br>
                {{ form.language }}
                <br>
                {{ form.submit }}
             </div>
          </fieldset>
       </form>
    </body>
 </html>

在Python shell中运行 formexample.py,并访问URL=> http://localhost:5000/contact 。 联系人表单将显示如下。

如果有错误信息,页面将如下所示 -

如果没有错误,将呈现 success.html页面的内容,如下所示 -

ython Flask 全流程全栈项目实战

xia仔ke:chaoxingit.com/4964/

获取资源:上方URL获取资源

Python Flask 全流程全栈项目实战

在现代软件开发领域中,全栈开发成为了一种越来越流行的趋势。全栈开发工程师不仅能够熟练应对前端和后端开发,还能够处理数据库设计和部署等各个环节。Python语言作为一种简洁、易读、易学的编程语言,被广泛应用于全栈开发中。而Flask作为Python语言中一款轻量级的web框架,也备受开发者的青睐。

在本文中,我们将介绍如何使用Python Flask完成一个全流程全栈项目实战。首先,我们需要明确项目的需求和功能。假设我们要开发一个简单的博客应用,用户可以注册账号、登录、发表文章、评论等功能。接下来,我们将按照以下步骤展开开发:

环境搭建:

要搭建一个基于Python和Flask的Web应用环境,你可以按照以下步骤操作:

1. 安装Python

确保你的系统上已经安装了Python。你可以在终端或命令行中输入 python --version 或者 python3 --version 来检查Python的版本。

2. 创建虚拟环境

使用Python的venv模块来创建一个虚拟环境,这将帮助你隔离项目依赖。

bash深色版本
python3 -m venv myflaskapp_env
source myflaskapp_env/bin/activate  # 在Unix或Mac OS中
myflaskapp_env\Scripts\activate     # 在Windows中

3. 安装Flask和其他依赖

在激活的虚拟环境中,使用pip安装Flask和其他可能需要的库,例如SQLAlchemy(用于数据库操作)和Flask-Migrate(用于数据库迁移)。

bash深色版本
pip install flask flask-sqlalchemy flask-migrate

4. 创建Flask项目

在你喜欢的代码编辑器中创建一个新的目录作为项目根目录,比如 myflaskapp。

bash深色版本
mkdir myflaskapp
cd myflaskapp

5. 初始化Flask应用

在项目根目录下创建一个名为 app.py 的文件,并添加以下代码来初始化Flask应用:

python深色版本
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///site.db'  # 使用SQLite数据库
db=SQLAlchemy(app)
migrate=Migrate(app, db)
if __name__=='__main__':
    app.run(debug=True)

6. 配置数据库

在上面的代码中,我们配置了数据库URI。你需要根据实际使用的数据库类型和设置进行修改。此外,你还可以创建一个单独的配置文件,如 config.py,并在 app.py 中导入它。

7. 定义模型

在 models.py 文件中定义你的数据模型。例如:

python深色版本
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)

8. 运行Flask应用

在你的虚拟环境中运行Flask应用:

bash深色版本
python app.py

这样,你就有了一个基本的Flask应用环境,可以开始构建你的Web应用了。记得在开发过程中,使用 deactivate 命令退出虚拟环境,以避免不必要的依赖冲突。

前端开发:

前端开发是Web应用的重要组成部分,负责处理用户界面的展示与交互。使用HTML、CSS和JavaScript(简称“前端三剑客”)是构建前端的基本方式,而引入如Bootstrap这样的前端框架可以极大地提升开发效率并保持界面的一致性和美观性。以下是具体步骤:

1. HTML 结构

HTML(HyperText Markup Language)用于定义网页的基本结构。在你的Flask应用中,HTML文件通常放在 templates 目录下。例如,创建一个基本的主页模板 index.html:

html深色版本
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My Flask App</title>
    <!-- 引入Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/    bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        <h1>Welcome to My Flask App</h1>
        <!-- 页面内容 -->
    </div>
    <!-- 引入Bootstrap JS -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery    /3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js    /1.16.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2    /js/bootstrap.min.js"></script>
</body>
</html>

2. CSS 样式

CSS(Cascading Style Sheets)用于美化HTML页面。可以创建一个 static/css/styles.css 文件来存放自定义样式,并在HTML中引用它。Bootstrap提供了许多预定义的类,可以直接应用于HTML元素以快速实现美观的布局。

3. JavaScript 交互

JavaScript 是用来增加网页动态功能的语言。在 static/js 目录下创建JavaScript文件,例如 main.js,并在HTML中引用。可以利用Bootstrap的JavaScript插件或者jQuery来简化DOM操作和事件处理。

4. 使用Bootstrap

Bootstrap是一个流行的前端框架,提供了响应式设计、预定义的组件和JavaScript插件。在上面的HTML示例中,我们通过CDN链接引入了Bootstrap的CSS和JS文件。你也可以下载Bootstrap并将其放在项目的静态文件目录中。

5. 集成到Flask

在Flask中,你可以使用 render_template 函数来渲染HTML模板。例如,在 app.py 中添加以下路由:

python深色版本
from flask import render_template
@app.route('/')
def index():
    return render_template('index.html')

这样,当你访问 / 路径时,Flask会渲染 templates/index.html 并显示在浏览器中。

6. 开发和测试

在本地开发环境中,你可以使用现代浏览器的开发者工具来调试CSS和JavaScript,确保前端页面按预期工作。

7. 响应式设计

Bootstrap支持响应式设计,这意味着你的页面在不同设备上(如手机和平板)都能良好显示。确保在开发过程中测试不同屏幕尺寸的兼容性。

通过这些步骤,你可以创建一个既美观又功能强大的前端界面,与后端的Flask应用无缝集成。

后端开发:

在后端开发中,使用Flask来处理HTTP请求和数据库操作是非常常见的做法。下面我将指导你如何实现用户注册、登录、发布文章以及评论功能。

1. 用户注册与登录

注册功能

首先,你需要创建一个用户模型,如果还没有的话。假设你已经有了一个User模型,现在让我们创建一个注册路由:

python深色版本
from flask import request, redirect, url_for
from werkzeug.security import generate_password_hash
@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method=='POST':
        username=request.form.get('username')
        password=request.form.get('password')
        hashed_password=generate_password_hash        (password, method='sha256')
        new_user=User(username=username, password=hashed_password)
        db.session.add(new_user)
        db.session.commit()
        return redirect(url_for('login'))
    return render_template('register.html')

登录功能

登录功能需要验证用户的用户名和密码:

python深色版本
from flask_login import login_user
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method=='POST':
        username=request.form.get('username')
        password=request.form.get('password')
        user=User.query.filter_by(username=username).first()
        if user and user.check_password(password):
            login_user(user)
            return redirect(url_for('index'))
        else:
            flash('Invalid username or password')
    return render_template('login.html')

2. 发布文章

为了实现文章的发布功能,你需要创建一个文章模型(如Article),并提供一个相应的路由:

python深色版本
from flask_login import current_user
@app.route('/create-article', methods=['GET', 'POST'])
@login_required  # 确保用户已登录
def create_article():
    if request.method=='POST':
        title=request.form.get('title')
        content=request.form.get('content')
        new_article=Article(title=title, content=content,         author=current_user)
        db.session.add(new_article)
        db.session.commit()
        return redirect(url_for('index'))
    return render_template('create_article.html')

3. 评论功能

评论功能通常涉及到文章和评论之间的关系,你需要创建一个评论模型(如Comment)并与文章模型建立关联。评论的路由可以如下所示:

python深色版本
@app.route('/article/<int:article_id>/comment', methods=['POST'])
@login_required
def add_comment(article_id):
    article=Article.query.get_or_404(article_id)
    comment_text=request.form.get('comment')
    new_comment=Comment(text=comment_text, author=current_user,     article=article)
    db.session.add(new_comment)
    db.session.commit()
    return redirect(url_for('article_detail', article_id=article_id))

4. 数据库操作

所有上述功能都需要与数据库交互,包括读取、插入、更新和删除数据。使用SQLAlchemy ORM可以方便地进行这些操作。

5. 安全性和认证

确保在处理敏感信息时,如用户密码,使用安全的方法进行存储(如bcrypt哈希)。同时,使用Flask-Login库管理用户会话和权限。

以上是实现基本用户管理、文章发布和评论功能的概览。在实际开发中,你可能还需要考虑错误处理、表单验证、分页、搜索等功能。

通过以上步骤,我们可以完成一个简单的全流程全栈项目实战。在实际开发中,可以根据项目需求和规模来进行适当的扩展和优化。Python Flask作为一款优秀的web框架,能够帮助开发者快速高效地完成项目开发,希望本文能对正在学习全栈开发的朋友们有所帮助。

文分享自众成翻译,介绍了一个将热门前端技术 Vue.js 与流行 Python 后端框架 Flask 结合的简单示例。推荐有兴趣采用类似技术栈的同学看看。


译者:枫林

链接:http://www.zcfy.cc/article/4491

原文:https://codeburst.io/full-stack-single-page-application-with-vue-js-and-flask-b1e036315532

在本教程中,我将向大家展示如何使用前端的 Vue.js 单页面应用和后端的 Flask 进行交互。

如果你只是想使用 Vue.js 库和 Flask 模板基本上是没什么问题的。但...好吧,其实还是有一个比较显而易见的问题:跟 Vue.js 一样,Jinji(模板引擎)也是使用双大括号来渲染页面,但已经有一个很好的解决方案 在这里 了。

我想要一个跟上面方案有点不同的例子。如果我要一个用 Vue.js(使用单页面组件,在 vue-router开启 HTML5 history 模式,还有使用其他一些非常棒的特性)框架的单页面和 Flask 做后台服务的应用?应该能按下面的要求工作:

  • Flask运行的服务可以访问 index.html首页和 Vue.js 应用

  • 在前端开发环境,使用 Webpack 和它提供的很多非常棒的功能

  • 可以从前端的单页面应用访问 Flask 的 API 接口

  • 以 Node.js 服务运行的前端开发环境同样也可以访问 API 接口

这看起来很有趣,不是吗?那就让我们开始吧。

你可以在github上查看所有的源代码:

https://github.com/oleg-agapov/flask-vue-spa

客户端

我用 vue-cli 命令行工具搭建起 Vue.js 的基础框架。如果你还没有安装,可以运行:

  1. $ npm install -g vue-cli

客户端和后端代码将会放到不同的文件夹下,初始化前端部分执行如下操作:

  1. $ mkdir flaskvue

  2. $ cd flaskvue

  3. $ vue init webpack frontend

以下是我通过安装向导的项目设置:

  • Vue build — Runtime only (Vue 构建的版本 - 运行时)

  • Install vue-router? — Yes (安装 vue-router? - 是)

  • Use ESLint to lint your code? — Yes (使用 ESLint 校验你的代码? - 是)

  • Pick an ESLint preset — Standard (选择 ESList 的预置版本 - 标准)

  • Setup unit tests with Karma + Mocha? — No (使用 Karma + Mocha 设置单元测试? - 否)

  • Setup e2e tests with Nightwatch? — No (使用 Nightwatch 设置端到端测试? - 否)

下一步:

  1. $ cd frontend

  2. $ npm install

  1. # after installation

  2. $ npm run dev

现在你可以开始设置 Vue.js 应用了。让我们先来添加些页面吧。

添加 Home.vueAbout.vuefrontend/src/components文件夹。像如下简单添加些内容:

  1. // Home.vue

  2. <template>

  3. <div>

  4. <p>Home page</p>

  5. </div>

  6. </template>

  1. // About.vue

  2. <template>

  3. <div>

  4. <p>About</p>

  5. </div>

  6. </template>

我们将在本地验证它们(通过地址栏访问)。现在我们要改变 frontend/src/router/index.js文件去一个个渲染我们的新组件:

  1. import Vue from 'vue'

  2. import Router from 'vue-router'

  3. const routerOptions=[

  4. { path: '/', component: 'Home' },

  5. { path: '/about', component: 'About' }

  6. ]

  7. const routes=routerOptions.map(route=> {

  8. return {

  9. ...route,

  10. component:=> import(`@/components/${route.component}.vue`)

  11. }

  12. })

  13. Vue.use(Router)

  14. export default new Router({

  15. routes,

  16. mode: 'history'

  17. })

现在如果输入 localhost:8080localhost:8080/about你应该看到相应的页面。

在我们构建生成项目静态资源前还需要修改它们的输出路径。在 frontend/config/index.js找到下面的两行

  1. index: path.resolve(__dirname, '../dist/index.html'),

  2. assetsRoot: path.resolve(__dirname, '../dist'),

然后成改如下内容

  1. index: path.resolve(__dirname, '../../dist/index.html'),

  2. assetsRoot: path.resolve(__dirname, '../../dist'),

所以, 包含 html/css/js 静态资源包的 /dist文件夹和/frontend在同一级目录下。现在你可以运行$ npm run build去构建项目了

后端

Flask 后端,我将使用 3.6 版本的 python。在根目录 /flaskvue文件夹下为后端代码和初始化虚拟环境创建新的子目录:

  1. $ mkdir backend

  2. $ cd backend

  3. $ virtualenv -p python3 venv

开启虚拟环境执行(mac系统):

  1. $ source venv/bin/activate

在 Windows 上开启请看这里 docs。

在虚拟环境中安装 Flask 如下:

  1. (venv) pip install Flask

现在让我们开始写 Flask 服务器端代码。在根目录下创建 run.py文件:

  1. (venv) cd ..

  2. (venv) touch run.py

然后添加以下代码到这个文件:

  1. from flask import Flask, render_template

  2. app=Flask(__name__,

  3. static_folder="./dist/static",

  4. template_folder="./dist")

  5. @app.route('/')

  6. def index:

  7. return render_template("index.html")

上面的代码和 Flask 入门教程 “Hello world” 上的代码稍有不同。最主要的不同点在于我们详细指明了前端的静态和模板文件夹输出到 /dist文件夹。然后在根目录下运行 Flask 服务。

  1. (venv) FLASK_APP=run.py FLASK_DEBUG=1 flask run

这将会在 localhost:5000开启一个后台服务。FLASK_APP指向服务启动文件,FLASK_DEBUG=1将会以调试模式运行。如果没有错误,你将会看到熟悉的首页,这样,服务器就成功运行 Vue 应用了。

与此同时如果你试图访问 /about页面将会出现一个错误。Flask 会抛出一个找不到请求地址的错误。实际上是因为在vue-router用了 HTML5 的 history 模式, 所以我们需要配置我们的后台服务去重定向所有的路由都跳转到index.html上。这在 Flask 上可以很简单做到。做如下修改:

  1. @app.route('/', defaults={'path': ''})

  2. @app.route('/<path:path>')

  3. def catch_all(path):

  4. return render_template("index.html")

现在地址 localhost:5000/about将会重定向到index.htmlvue-router将会在它自己内部处理。

添加 404 页面

因为在我们的后台服务里设置捕捉所有路由是非常困难的,所以我们用 Flask 捕捉 404 错误会重定向 所有请求到index.html(连同不存在的页面)。在 Vue.js 应用里处理未定义的路由。当然,所有的工作均可在我们的路由文件设置。

frontend/src/router/index.js增加一行:

  1. const routerOptions=[

  2. { path: '/', component: 'Home' },

  3. { path: '/about', component: 'About' },

  4. { path: '*', component: 'NotFound' }

  5. ]

通配符 '*'vue-router里的含义是以上路由定义之外的情况。现在我们需要在/components文件夹新建NotFound.vue文件。我简单地创建它:

  1. // NotFound.vue

  2. <template>

  3. <div>

  4. <p>404 - Not Found</p>

  5. </div>

  6. </template>

现在 通过 npm run dev重新启动前台服务然后随意输入网址像localhost:8080/gljhewrgoh。你应该看到 “Not Found” 两个单词。

添加后端 API 接口

我的 Vue.js/Flask 教程的最后一个例子将在后端创建一个 API 接口然后通过前端来调用它。我将创建一个随机返回数字1到100的简单端口。

打开 run.py新增如下代码:

  1. from flask import Flask, render_template, jsonify

  2. from random import *

  3. app=Flask(__name__,

  4. static_folder="./dist/static",

  5. template_folder="./dist")

  6. @app.route('/api/random')

  7. def random_number:

  8. response={

  9. 'randomNumber': randint(1, 100)

  10. }

  11. return jsonify(response)

  12. @app.route('/', defaults={'path': ''})

  13. @app.route('/<path:path>')

  14. def catch_all(path):

  15. return render_template("index.html")

我首先从 Flask 资源库导入 random库和jsonify函数。然后我增加一个返回 JSON 数据格式的新路由/api/random, 如下:

  1. {

  2. "randomNumber": 36

  3. }

你可以通过地址: localhost:5000/api/random来测试这个路由。

到这里,服务端的工作已经完成了。该到客户端上场了。我将修改 Home.vue组件来显示我的随机数字:

  1. <template>

  2. <div>

  3. <p>Home page</p>

  4. <p>Random number from backend: {{ randomNumber }}</p>

  5. <button @click="getRandom">New random number</button>

  6. </div>

  7. </template>

  8. <script>

  9. export default {

  10. data {

  11. return {

  12. randomNumber: 0

  13. }

  14. },

  15. methods: {

  16. getRandomInt (min, max) {

  17. min=Math.ceil(min)

  18. max=Math.floor(max)

  19. return Math.floor(Math.random * (max - min + 1)) + min

  20. },

  21. getRandom {

  22. this.randomNumber=this.getRandomInt(1, 100)

  23. }

  24. },

  25. created {

  26. this.getRandom

  27. }

  28. }

  29. </script>

在这一步,我将在客户端模拟随机数的生成。所以,组件的工作过程如下:

  • 初始变量 randomNumber等于0

  • methods部分,我们用getRandomInt(min, max)函数从指定区间返回一个数字,getRandom函数将调用上一个函数生成一个值赋给randomNumber

  • 之后在组件被创建时调用 getRandom方法给randomNumber赋个初始数值

  • 在按钮点击事件里,我们将触发 getRandom方法去得到一个数值

现在,在首页上你将看到由前端生成的随机数。让我们继续来连接后端。

我将用 axios 库来连接后端。它将允许我们创建能返回 Promise对象的 HTTP 请求。我们先安装它:

  1. (venv) cd frontend

  2. (venv) npm install --save axios

再次打开 Home.uve,修改<script>部分代码:

  1. import axios from 'axios'

  2. methods: {

  3. getRandom {

  4. // this.randomNumber=this.getRandomInt(1, 100)

  5. this.randomNumber=this.getRandomFromBackend

  6. },

  7. getRandomFromBackend {

  8. const path=`[http://localhost:5000/api/random`](http://localhost:5000/api/random`)

  9. axios.get(path)

  10. .then(response=> {

  11. this.randomNumber=response.data.randomNumber

  12. })

  13. .catch(error=> {

  14. console.log(error)

  15. })

  16. }

  17. }

在文件顶部,我们先导入 axios 库。然后用 axios 去异步调用新方法 getRandonFromBackend接收返回的结果。最后,getRandom方法调用getRandomFromBackend去获取随机值。

保存文件,打开浏览器,再次运行前端开发服务器环境,刷新 localhost:8080然后... 你应该看到控制台报了没有随机值的错误。但不用担心,一切正常运行中。我们得到 cors 的错误,它的意思是我们的 Flask 后台 API 默认不对其他的域名和端口(我们的例子运行的是 Vue.js 应用)开放。当你用npm run build生成包然后打开localhost:5000(Flask 服务)你会看到应用正常运行不再报错了。但如果每次在客户端改了一点东西都要重新构建包,显然不是很方便。

Flask 的 CORS 插件允许我们为访问 API 创建规则。插件叫 flask-cors,我们先来安装它:

  1. (venv) pip install -U flask-cors

你可以通过阅读文档选择更好的方法来在你的服务器上开启 CORS。我这里将会用资源指定的方法应用 {"origins": "*"}去允许所有/api/*下的路由(所以任何人都可以访问/api接口)。修改run.py

  1. from flask_cors import CORS

  2. app=Flask(__name__,

  3. static_folder="./dist/static",

  4. template_folder="./dist")

  5. cors=CORS(app, resources={"/api/*": {"origins": "*"}})

改好之后,你就可以从前端的开发环境调用 Flask API 接口了。

太神奇了 ?!

现在你拥有了一个用你喜爱的技术完成的全栈应用。

后记

最后我想说说如何改进这个方案。

首先,在你代码里所有使用到的环境变量。主要是关于使用 FLASK_DEBUG变量。我们在 CORS 设置中使用到它。例如,如果服务运行在开发环境设置FLASK_DEBUG=1你可以允许任何的请求源。如果不是,禁用 CORS 或者只允许可信源请求。

另外一个改进是避免在客户端硬编码 API 路由。也许你需要思考为 API 接口创建映射表。所以当你改变 API 路由,你所需要做的只是更新映射表。前端的调用接口将不需要改变。

还有个小建议 - 我通常同时开启至少3个终端窗口:一个运行 Flask,二个运行 Vue.js(第一个运行 Node.js 服务,第二个用来做项目构建打包)。

源代码:https://github.com/oleg-agapov/flask-vue-spa

最后非常感谢你的阅读!

回复下方「关键词」,获取优质资源

回复关键词「 pybook03」,立即获取主页君与小伙伴一起翻译的《Think Python 2e》电子版

回复关键词「pybooks02」,立即获取 O'Reilly 出版社推出的免费 Python 相关电子书合集

回复关键词「书单02」,立即获取主页君整理的 10 本 Python 入门书的电子版

印度小伙写了套深度学习教程,Github上星标已经5000+

上百个数据文件合并,只能手动复制粘贴?教你一招十秒搞定!

一个提升图像识别准确率的精妙技巧

一文读懂:从 Python 打包到 CLI 工具

如何使用 Python 进行时间序列预测?

美亚Kindle排名第一的Python 3入门书,火遍了整个编程圈

十分钟搭建私有 Jupyter Notebook 服务器

使用 Python 制作属于自己的 PDF 电子书

12步轻松搞定Python装饰器

200 行代码实现 2048 游戏

题图:pexels,CC0 授权。

点击阅读原文,查看更多 Python 教程和资源。