Python Web框架 Flask - Flask表单、项目结构、文件上传、发送邮件

Flask表单

Flask项目开发中针对提交表单的校验,可以使用Flask-WTF扩展库进行快速的字段校验

安装Flask-WTF

pip install flask-wtf

定义form.py文件进行表单验证

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired, EqualTo


class UserRegisterForm(FlaskForm):
    username = StringField('用户名', validators=[DataRequired()])
    password = StringField('密码', validators=[DataRequired()])
    password2 = StringField('确认密码', validators=[DataRequired(), EqualTo('password', '密码不一致')])
    submit = SubmitField('提交')

定义注册视图函数

当HTTP请求为GET时,将表单验证对象返回给页面。

当HTTP请求为POST时,通过方法validate_on_submit()方法进行字段校验和提交判断,如果校验失败,则可以从form.errors中获取错误信息。

如果验证通过,则从form.字段.data中获取到字段的值。

@blue.route('/register/', methods=['GET', 'POST'])
def register():
    form = UserRegisterForm()
    if request.method == 'GET':
        return render_template('register.html', form=form)

    if request.method == 'POST':
        if form.validate_on_submit():
            username = form.username.data
            password = form.password.data
            # 保存
            user = User()
            user.username = username
            password = generate_password_hash(password)
            user.password = password
            user.save()
            return '创建成功'

        else:
            return render_template('register.html', form=form)

使用表单后,会在模板中自动生成表单标签
在括号中可以自定义属性,包括type、style等

    <h2>注册</h2>
    <form action="" method="post">
        {{ form.csrf_token }}
        {{ form.username.label }} : {{ form.username }} <br>
        {{ form.password.label }} : {{ form.password(type='password') }} <br>
        {{ form.password2.label }} : {{ form.password2(type='password') }} <br>
        {{ form.submit }}
    </form>

Flask文件上传

模板定义

form表单中定义上传文件的字段,定义type='file'。注意上传的表单中一定要添加enctype="multipart/form-data"参数。

    <form action="" method="post" enctype="multipart/form-data">
        图片: <input type="file" name="icon"><br>
        <input type="submit" value="提交">
    </form>

图片保存

图片的保存可以直接通过request.files获取模板中上传的图片,并调用save()方法进行保存。

@blue.route('/icon/', methods=['GET', 'POST'])
def icon():
    if request.method == 'GET':
        return render_template('icon.html')

    if request.method == 'POST':
        # 1.获取图片
        icon = request.files.get('icon')
        # 2.保存图片
        # path: E:/workspace/flask/day05/static/media/xxx.jpg
        path = os.path.join(MEDIA_PATH, icon.filename)
        icon.save(path)

        # 3.修改字段
        user = User.query.filter(User.username == 'aaa').first()
        user.icon = icon.filename
        user.save()
        return redirect(url_for('user.index'))

图片渲染

案例的场景是修改当前登录系统用户的icons字段,在模板中可以通过current_user参数获取当前登录系统的用户对象,并访问icons属性即可获取到存储在数据库中的图片路径。

    <img src="/static/media/{{ user.icon }}" style="width: 500px">

项目结构

manage.py - 项目启动

from flask_script import Manager
from utils.app import create_app

# 获取flask对象app
app = create_app()
# 管理app
manage = Manager(app)

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

app.py - 初始化项目,加载配置,蓝图注册

from flask import Flask

from utils.config import Conf
from app.views import blue
from app.models import db
from utils.settings import STATIC_PATH, TEMPLATE_PATH


def create_app():

    app = Flask(__name__,
                static_folder=STATIC_PATH,
                template_folder=TEMPLATE_PATH)
    # 加载配置
    app.config.from_object(Conf)
    # 蓝图
    app.register_blueprint(blueprint=blue, url_prefix='/user')
    # 初始化
    db.init_app(app)

    return app

config - 配置信息(键值对形式)

from utils.functions import get_sqlalchemy_uri
from utils.settings import DATABASE


class Conf():
    SQLALCHEMY_DATABASE_URI = get_sqlalchemy_uri(DATABASE)
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    PRESERVE_CONTEXT_ON_EXCEPTION = False
    SECRET_KEY = 'qwertyuiopasdfghjklzxcvbnm1234567890'

settings.py - 经常修改的详细配置信息 - static、templates、media等路径的配置


import os

# 基础路径
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# static路径
STATIC_PATH = os.path.join(BASE_DIR, 'static')
# templates路径
TEMPLATE_PATH = os.path.join(BASE_DIR, 'templates')
# media路径
MEDIA_PATH = os.path.join(STATIC_PATH, 'media')


DATABASE = {
    'NAME': 'flask',
    'USER': 'root',
    'PASSWORD': '123456',
    'HOST': '127.0.0.1',
    'PORT': '3306',
    'ENGINE': 'mysql',
    'DRIVER': 'pymysql'
}

在functions.py文件中获得mysql连接

def get_sqlalchemy_uri(DATABASE):
    # mysql+pymysql://root:123456@127.0.0.1:3306/flask
    user = DATABASE['USER']
    password = DATABASE['PASSWORD']
    host = DATABASE['HOST']
    port = DATABASE['PORT']
    name = DATABASE['NAME']
    engine = DATABASE['ENGINE']
    driver = DATABASE['DRIVER']

    return f'{engine}+{driver}://{user}:{password}@{host}:{port}/{name}'

自定义状态码清单

USER_LOGIN_PARAMS_IS_INVALID = {'code': 10001, 'msg': '请填写完整信息'}
USER_LOGIN_USERNAME_OR_PASSWORD_ERROR = {'code': 10002, 'msg': '用户名或者密码错误'}
SUCCESS = {'code': 200, 'msg': '请求成功'}

Flask邮件发送

from flask import Flask

from flask_mail import Mail, Message


app = Flask(__name__)

app.config['MAIL_SERVER'] = 'smtp.163.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'ypcc624@163.com'
app.config['MAIL_PASSWORD'] = 'abcd1234'

mail = Mail(app)


@app.route('/send_mail/')
def send_mail():
    message = Message('邮件轰炸机', sender=app.config["MAIL_USERNAME"], recipients=["779598160@qq.com"])
    message.body = '成功啦,开始轰炸啦'

    send_email(message)

    return '发送成功'


def send_email(msg):
    mail.send(msg)


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

参数以及说明

首先需要开启客户端授权码,并设置授权码。

安装flask-mail

pip install flask-mail

设置的参数定义如下:
MAIL_SERVER: 电子邮件服务器的主机名或IP地址, 默认为localhost

MAIL_PORT: 电子邮件服务器的端口,默认为25

MAIL_USE_TLS: 启用传输层安全协议,默认为False

MAIL_USE_SSL: 启用安全套接层协议, 默认为False

MAIL_USERNAME: 邮件账户的用户名

MAIL_PASSWORD:邮件账户的密码,为在163中设置的授权码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容