从零开始搭建 flask 博客实验(2)

在开始之前,先来看下项目的整体结构。

复制代码
flask
├── app
│   ├── __init__.py
│   ├── routes.py
│   └── templates
│       ├── base.html
│       └── index.html
├── myblog.py

最终目录结构

flask_tutorial/

├── app/

│ ├── init.py

│ ├── routes.py

│ ├── forms.py

│ └── templates/

│ ├── base.html

│ ├── index.html

│ └── login.html

├── config.py

└── myblog.py

前面已经讲了一个简单的 hello world 和模板的应用, 但是在网页中这些肯定是不够用的,所以接下来讲一讲登录和注册都常用的表单。

首先安装 flask-wtf,这是表单的集成模块。

本节目标:实现:

  • 表单模块 flask-wtf

  • 配置文件 config.py

  • 登录表单 forms.py

  • 登录页面 login.html

  • 登录路由 /login

  • 修改导航栏可点击"登录"

复制代码
(venv) duke@coding:~/flask_tutorial/flask$ pip install flask-wtf

为了确保表单提交过来的是安全的,所以我们设定一个安全钥匙。当用户请求表单时,将这个钥匙给用户,然后用户提交表单的时候,将这个钥匙和我们服务器中的钥匙比对一下,如果安全的话就接收用户表单里的信息,如果比对不成功,那说明这个用户提交过来的数据有问题喽,拒绝他!

因此,咱们要设置一个这样的钥匙,但是接下也要设置数据库的位置和其他一些东西。想一想,这些需要配置的东西放到一个文件里,需要的话用一下多方便,因此要创建一个配置文件。

复制代码
(venv) duke@coding:~/flask_tutorial/flask$ touch config.py

config.py : 配置信息

复制代码
class Config(object):
    #设置密匙要没有规律,别被人轻易猜到哦
    SECRET_KEY = 'a9087FFJFF9nnvc2@#$%FSD'

钥匙设置好了,但是怎么使用呢?

app/_ _ init _ _.py : 使用配置文件 config.py 中的内容

复制代码
from flask import Flask
#导入配置文件
from config import Config
app = Flask(__name__)
#添加配置信息
app.config.from_object(Config)

from app import routes

首先测试一下是否配置成功

复制代码
(venv) duke@coding:~/flask_tutorial/flask$ python
Python 3.6.4 (default, May  3 2018, 19:35:55) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from myblog import app
>>> app.config['SECRET_KEY']
'a9087FFJFF9nnvc2@#$%FSD'

判断表格填写的是否正确,是否有未填写,格式是否有错误这些问题有集成好的方法供我们使用,我们只用写一个规定方法格式的文件即可。

新建一个 forms.py,用来处理表单信息。

复制代码
(venv) duke@coding:~/flask_tutorial/flask$ touch app/forms.py

app/forms.py : 处理登录界面的信息.

复制代码
from flask_wtf import FlaskForm
from wtforms import StringField,PasswordField,BooleanField,SubmitField
from wtforms.validators import DataRequired

class LoginForm(FlaskForm):
    #DataRequired,当你在当前表格没有输入而直接到下一个表格时会提示你输入
    username = StringField('用户名',validators=[DataRequired(message='请输入名户名')])
    password = PasswordField('密码',validators=[DataRequired(message='请输入密码')])
    remember_me = BooleanField('记住我')
    submit = SubmitField('登录')

处理登录界面表单的文件写好了,那么现在当然就是要写一个登录界面啦。

在模板 templates 文件夹中创建 login.html

复制代码
(venv) duke@coding:~/flask_tutorial/flask$ touch app/templates/login.html

app/templates/login.html : 完成登录模板

复制代码
{% extends 'base.html' %}

{% block content %}
     <h1>登 录</h1>
    <form action="" method="post">
        #用来实现在配置中激活的csrf保护
        {{ form.hidden_tag() }}
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}
        </p>
        <p>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}
        </p>
        <p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
        <p>{{ form.submit() }}</p>
    </form>
{% endblock %}

模板建立完成,接下来要对试图函数进行修改。

app/routes.py : 创建一个表单实例

复制代码
from flask import render_template
from app import app
#导入表单处理方法
from app.forms import LoginForm

#前面的就不列举出来了,接着前面的写就可以了
#.......

@app.route('/login')
def login():
    #创建一个表单实例
    form = LoginForm()
    return render_template('login.html',title='登 录',form=form)

对模板中的基类进行一个修改,因为上面跳转只有到首页的,添加一个跳转至登录界面的。

app/templates/base.html : 修改基类模板导航栏

复制代码
<body>
   <div>博客 : 
       <a href="/index">首页</a>
       <a href="/login">登录</a>

    </div>
      {% block content %}

      {% endblock %}
</body>

好的,现在先访问一下试试看,但是现在还不能登录哦。因为处理登录数据的部分还没有写,现在只是测试一下页面是否正确。

OK,看起来还不错,那接下来就来完成处理登录数据的部分。我在这里会用到闪现来传递信息,重定向来返回页面。

app/routes.py :处理表单数据

复制代码
from flask import render_template,flash,redirect
from app import app
from app.forms import LoginForm

#前面的就不列举出来了,接着前面的写就可以了
#.......

@app.route('/login',methods=['GET','POST'])
def login():
    form = LoginForm()
    #验证表格中的数据格式是否正确
    if form.validate_on_submit():
        #闪现的信息会出现在页面,当然在页面上要设置
        flash('用户登录的名户名是:{} , 是否记住我:{}'.format(
            form.username.data,form.remember_me.data))
        #重定向至首页
        return redirect('/index')
    #首次登录/数据格式错误都会是在登录界面
    return render_template('login.html',title='登录',form=form)

既然有需要闪现的信息,那么页面模板就要随之修改。

app/templates/base.html : 添加需要闪现的界面格式。

复制代码
<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
     {% if title %}
        <title>{{ title }} - 博客</title>
        {% else %}
        <title>欢迎来到博客!</title>
        {% endif %}
    </head>
    <body>
       <div>博客 :
           <a href="/index">首页</a>
           <a href="/login">登录</a>
       </div>
       <hr>
       {% with messages = get_flashed_messages() %}
           {% if messages %}
            <ur>
                {% for message in messages %}
                    <li>{{ message }}</li>>
                {% endfor %}
            </ur>
           {% endif %}         
       {% endwith %}

        {% block content %}  {% endblock %}
    </body>
</html>

登录界面不是很完善,因为哪里出错了没有显示在页面上呀,用户看不到,所以要完善登录页面。

app/templates/login.html : 完善显示信息

复制代码
{% extends 'base.html' %}

{% block content %}
     <h1>登 录</h1>
    <form action="" method="post">
        {{ form.hidden_tag() }}
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}<br>
            {% for error in form.username.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}

        </p>
        <p>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}<br>
            {% for error in form.password.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}

        </p>
        <p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
        <p>{{ form.submit() }}</p>
    </form>
{% endblock %}

运行一遍,可以看到结果很好。但是在成功的喜悦当中又有着些许遗憾,为啥?如果方法上的路由发生了变化,那么模板上的链接就失效了呀,为了解决这个问题,可以使用 url_for。这是根据视图函数名返回 url,就不用担心这个问题了。

app/templates/base.html : 修改模板中的基类的导航栏

复制代码
<div>博客 :
           <a href="{{ url_for('index') }}">首页</a>
           <a href="{{ url_for('login') }}">登录</a>
 </div>

既然模板中进行了修改,那么视图函数中肯定要进行修改。

app/routes.py : 添加 url_for

复制代码
from flask import render_template,flash,redirect,url_for

#不用修改
#......

@app.route('/login',methods=['GET','POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        #不用修改
        #......
        return redirect(url_for('index'))
    #.............

运行测试一下,会发现...... 很流畅!

最终效果:

相关推荐
武子康10 分钟前
大数据-159 Apache Kylin Cube 实战:Hive 装载与预计算加速(含 Cuboid/实时 OLAP,Kylin 4.x)
大数据·后端·apache kylin
傻啦嘿哟19 分钟前
Python将Excel工作表转换为PDF:从入门到实战
python·pdf·excel
疯狂的程序猴26 分钟前
Mac 抓包软件怎么选?从 HTTPS 调试、TCP 数据流分析到多工具协同的完整抓包方案
后端
老鱼说AI32 分钟前
BPE编码从零开始实现pytorch
开发语言·人工智能·python·机器学习·chatgpt·nlp·gpt-3
BingoGo37 分钟前
使用 PHP 和 Raylib 也可以开发贪吃蛇游戏
后端·php
陳陈陳40 分钟前
AIGC 时代,用自然语言操作数据库:SQLite + LLM 的轻量级实践
前端·数据库·python
爱分享的鱼鱼40 分钟前
Spring Boot如何整合Redis
后端
知其然亦知其所以然41 分钟前
别再被问住!Redis Cluster 一文彻底讲透(Java 面试必背)
redis·后端·面试
codercwh1 小时前
3 分钟上手 Claude Code!API 中转站让 AI 编程效率翻倍
后端
林炳然1 小时前
Python-Basic Day-4 函数-基础知识
python