Flask学习笔记(一)

这一部分包括了flask 的基础知识点和一个简单的博客系统,代码仓库,之后的学习笔记也会一直更新。

1.环境

conda reate -n flask python
conda activate flask
pip install flask -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

2.知识点

2.1.第一个flask项目

首先项目的结构

static(文件夹,放css,js,图片文件等)
templates(文件夹,放html文件)
1.第一个flask项目.py

from flask import Flask#flask包中导入Flask类
app=Flask(__name__)#使用Flask类创建一个对象
#创建路由和试图函数的映射
@app.route("/")
def hello():
    return "hello world"
if __name__=="__main__":
    app.run()

2.2.修改Debug,host,port配置

app.run(debug=True,host="0.0.0.0",port="5001")

2.3.url与视图函数

有参路由,路由传参

from flask import Flask,request
app=Flask(__name__)
#1.url:http[80]/https[443]://www.域名.com:port/path
@app.route("/")
def hello():
    return "hello world"
@app.route("/profile/")
def profile():
    return "个人中心"
#2.有参路由,路由传参,利于seo优化
@app.route("/blog/<int:blog_id>/")
def blog_detail(blog_id):
    return "您访问的博客是:%d" %blog_id
#3.查询字符串的方式传参:http://172.20.10.5:5000/book/list?page=9,默认page=1,不利于seo优化,一般后台用这种。
@app.route("/book/list/")
def book_list():
    page=request.args.get(key="page",default=1,type=int)
    return f"这是第{page}页"
if __name__=="__main__":
    app.run(debug=True,host="0.0.0.0",port="5000")

#2.路由传参的参数类型:
string:默认的,接收没有任何斜杠的文本。
int:整型
float:浮点类型
path:和string类型类似,但可以接收斜杠
uuid:uuid字符,全宇宙唯一的标识符,一般用来作为表的主键。
any:可以指定多种路径共用。

@app.route('/<any(blog,user):url_path>/<id>/')
def two(url_path,id):
    if url_path=='blog':
        return "博客详情:%s"%id
    else:
        return "用户详情:%s"%id

(url_for)反向查找路径

@app.route("/")
def hello():
    print(url_for('my_list',page=1,count=2))#输出是:/list/1?count=2
    return "hello"
@app.route("/list/<page>/")
def my_list():
    return "list"

2.4.模板渲染

1.templates/blog.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <titel>博客</titel>
</head>
<body>
    <h1>博客id是:{{blog_id}}</h1>
    <p>博客名是:{{user_name}}</p><!--1.取变量值*/-->
    <div>{{user.username}}/{{user.email}}</div><!--2.取对象属性*/-->
    <div>{{person.u}}/{{person["e"]}}</div><!--1.字典的取值有两种方式*/-->
</body>
</html>

2.模板渲染.py

from flask import Flask,render_template
app=Flask(__name__)
@app.route("/")
def hello():
    return render_template("index.html")#1.自动去templates目录下面找index.html文件,并渲染
@app.route("/blog/<blog_id>/")
def blog_detail(blog_id):
    return render_template("blog.html",blog_id=blog_id,user_name="zoe")#2.传参数给html去渲染,html:{{var_name}}
class User:
    def __init__(self,username,email):
        self.username=username
        self.email=email
@app.route("/information/")
def information():
    user=User(username="张三",email="111@zs")
    person={"u":"李四","e":"222@ls"}
    return render_template("blog.html",user=user,person=person)#3.传的参数是对象,字典。
if __name__=="__main__":
    app.run(debug=True,host="0.0.0.0",port="5000")

2.5.过滤器

传到html的变量处理再渲染,这时用管道操作符(|),连接自带的过滤器或者自定义的过滤器.
1.filter.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <titel></titel>
</head>
<body>
    <div>{{user.username}}长度是:{{user.username|length}}</div><!--1.管道操作符后连接length自带的过滤器-->
    <div>{{mytime|dformat}}</div><!--2.管道操作符后连接的是自定义的过滤器-->
</body>
</html>

2.过滤器.py

from flask import Flask,render_template
from datetime import datetime
app=Flask(__name__)
class User:
    def __init__(self,username,email):
        self.username=username
        self.email=email
#2.自定义过滤器
def datetime_format(value,format="%Y年%m月%d日 %H:%M"):
    return value.strftime(format)
app.add_template_filter(datetime_format,"dformat")#将自定义的datetime_format,以dformat为名添加到app的过滤器中
@app.route("/filter/")
def filter():
    user=User(username="张三",email="111@zs")
    mytime=datetime.now()
    return render_template("filter.html",user=user,mytime=mytime)#1.user这里在html中会用到自带的过滤器,给出变量的length
if __name__=="__main__":
    app.run(debug=True,host="0.0.0.0",port="5000")

2.6.控制语句for与if

1.control.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta chatset="UTF-8">
        <title>控制语句if与for</title>
    </head>
    <body>
        {% if age>18 %}
            <div>你已成年</div>
        {% elif age==18 %}
            <div>你今年成年</div>
        {% else %}
            <div>你未成年啊</div>
        {% endif %}
        {% for book in books %}
            <div>书名:{{book.name}},作者:{{book.author}}</div>
        {% endfor %}
    </body>
</html>

2.控制语句.py

from flask import Flask,render_template
app=Flask("__name__")
@app.route("/control/")
def control():
    age=8
    books=[{"name":"三国演义","author":"罗贯中"},{"name":"水浒传","author":"施耐庵"}]
    return render_template("control.html",age=age,books=books)
if __name__=="__main__":
    app.run(debug=True,host="0.0.0.0",port="5000")

2.7.模板继承

1.base.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}{% endblock %}</title>
    </head>
    <body>
        这是base文字
        {% block body %}{% endblock %}
    </body>
</html>

2.child1.html

{% extends "base.html"%}

{% block title %}
child1的title
{% endblock %}

{% block body %}
child1的body
{% endblock %}

3.模板继承.py

from flask import Flask,render_template
app=Flask("__name__")
@app.route("/child1/")
def child1():
    return render_template("child1.html")
if __name__=="__main__":
    app.run(debug=True,host="0.0.0.0",port="5000")

2.8.加载静态文件

在html文件里加载static里面的css,js,picture等文件。
1.alert.js

alert("js执行的弹窗");

2.style.css

body{
    background-color:pink;
}

3.static.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>静态文件加载</title>
        <link rel="stylesheet" href="{{url_for('static',filename='css/style.css')}}"><!--加载css样式文件-->
        <script src="{{url_for('static',filename='js/alert.js')}}"></script><!--加载js文件-->
    </head>
    <body>
        <img src="{{url_for('static',filename='img/1.jpg')}}" alt=""><!--加载img文件-->
    </body>
</html>

4.加载静态文件.py

from flask import Flask,render_template
app=Flask("__name__")
@app.route("/my_static/")
def my_static():
    return render_template("static.html")
if __name__=="__main__":
    app.run(debug=True,host="0.0.0.0",port="5000")

2.9.mysql操作

2.9.1.安装mysql

这里可以参考博文
然后在flask环境中

pip install pymysql
pip install flask-sqlalchemy

创建一个名为database_learn的数据库
在这里插入图片描述

2.9.2.在python中连接数据库并测试是否连接成功

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
HOSTNAME="127.0.0.1"
PORT=3306
USERNAME="root"
PASSWORD="xxxx"
DATABASE="database_learn"
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']=f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"
db=SQLAlchemy(app)#1.sqlalchemy读取app的config,然后自动连接,
#2.测试sql是否连接成功,输出(1,),表示连接成功
with app.app_context():
    with db.engine.connect() as conn:
        rs=conn.execute(text("select 1"))
        print(rs.fetchone())
@app.route("/")
def hello():
    return "hello"
if __name__=="__main__":
    app.run()

2.9.3.创建表并增删改查

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
HOSTNAME="127.0.0.1"
PORT=3306
USERNAME="root"
PASSWORD="xxxx"
DATABASE="database_learn"
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']=f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"
db=SQLAlchemy(app)
#1.ORM对象关系映射,一个ORM模型与数据库中的一个表对应:创建一个类就是创建了一张表,实例化一个对象就是插入了一条数据
class User(db.Model):
    __tablename__="user"#表名
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)#设为主键,自动增长
    username=db.Column(db.String(100),nullable=False)#不可置空
    password=db.Column(db.String(100),nullable=False)
with app.app_context():
    db.create_all()#开始创建表
#1.增:
@app.route("/user/add/")
def add_user():
    user=User(username="张三",password="123")#1.创建ORM对象
    db.session.add(user)#2.将ORM对象添加到db.session
    db.session.commit()#3.将db.session中的改变同步到数据库中
    return "用户创建成功"
#2.查询:get查找(根据主键查找);filter_by查找
@app.route("/query/")
def query():
    #1.get查找
    # user=User.query.get(1)
    # print(f"{user.id}:{user.username}--{user.password}")
    #2.filter_by查找
    users=User.query.filter_by(username="张三")#是一个Query类数组
    for user in users:
        print(user.username)
    return "查找成功"
#3.改:
@app.route("/user/update/")
def update_user():
    user=User.query.filter_by(username="张三").first()
    user.password="gai"
    db.session.commit()
    return "数据修改成功"
#4.删:
@app.route("/user/delete/")
def delete_user():
    user=User.query.get(1)
    db.session.delete(user)
    db.session.commit()
    return "删除成功"
@app.route("/")
def hello():
    return "hello"
if __name__=="__main__":
    app.run(debug=True,host="0.0.0.0",port="5000")

2.9.4.外键与表关系

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
HOSTNAME="127.0.0.1"
PORT=3306
USERNAME="root"
PASSWORD="190023"
DATABASE="database_learn"
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']=f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"
db=SQLAlchemy(app)
class User(db.Model):
    __tablename__="user"#表名
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)#设为主键,自动增长
    username=db.Column(db.String(100),nullable=False)#不可置空
    password=db.Column(db.String(100),nullable=False)
class Article(db.Model):
    __tablename__="article"
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)
    title=db.Column(db.String(200),nullable=False)
    content=db.Column(db.Text,nullable=False)
    #添加两表之间的外键
    author_id=db.Column(db.Integer,db.ForeignKey("user.id"))
    #添加两表之间的对象关系
    author=db.relationship("User",backref="articles")#article.author返回User的对象,user.articles返回Article的对象
with app.app_context():
    db.create_all()
#增
@app.route("/article/add/")
def ar_ad():
    article1=Article(title="西游记",content="xxxxxxxxxxxxxxxx")
    article1.author=User.query.get(2)
    article2=Article(title="红楼梦",content="yyyyyyyyyyyyyyyy")
    article2.author=User.query.get(2)
    #添加到session中
    db.session.add_all([article1,article2])
    #session中的数据同步到数据库中
    db.session.commit()
    return "文章添加成功"
#查
@app.route("/article/query/")
def ar_qu():
    user=User.query.get(2)
    for article in user.articles:
        print(article.title)
    return "文章查找成功"
if __name__=="__main__":
    app.run(debug=True,host="0.0.0.0",port="5000")

2.9.5.flask-migrate迁移ORM模型

set flask环境

pip install flask-migrate
pip install flask-migrate --upgrade
pip install flask-sqlalchemy --upgrade
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
HOSTNAME="127.0.0.1"
PORT=3306
USERNAME="root"
PASSWORD="190023"
DATABASE="database_flask"
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']=f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"
db=SQLAlchemy(app)
migrate=Migrate(app,db)
#ORM模型映射的三步
#1.flask db init:秩序执行一次,相当于仓库初始化
#2.flask db migrate:识别ORM模型的改变,生成迁移脚本
#3.flask db upgrade:

3.博客项目实战

3.1 结构搭建

blueprints文件夹,放蓝图
static文件夹放静态文件
templates文件夹放html文件
models.py放模型文件
config.py放配置文件
exts.py放扩展文件
app.py汇总主程序文件

app.py:

from flask import Flask
import config
from exts import db
from models import UserModel
from blueprints.qa import bp as qa_bp
from blueprints.auth import bp as auth_bp
app=Flask(__name__)
#1.绑定配置文件config.py
app.config.from_object(config)
#2.绑定exts文件的SQLAlchemy
db.init_app(app)
#3.绑定蓝图
app.register_blueprint(qa_bp)
app.register_blueprint(auth_bp)
if __name__=="__main__":
    app.run()

3.2 连接数据库

首先在config文件夹中设置数据库连接的配置文件

HOSTNAME="127.0.0.1"
PORT='3306'
DATABASE="blog"
USERNAME="root"
PASSWORD="xxxx"
DB_URI="mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8".format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
SQLALCHEMY_DATABASE_URI=DB_URI

然后在models文件里定义自己的表

from exts import db
from datetime import datetime
class UserModel(db.Model):
    __tablename__="user"
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)
    username=db.Column(db.String(100),nullable=False)
    password=db.Column(db.String(100),nullable=False)
    email=db.Column(db.String(100),nullable=False,unique=True)
    join_time=db.Column(db.DateTime,default=datetime.now)

在app文件里导入表模型,并且进行数据库的映射

from models import UserModel
#4.数据库映射
migrate =Migrate(app,db)

最后在终端进行ORM模型映射的三步

#1.flask db init:秩序执行一次,相当于仓库初始化
#2.flask db migrate:识别ORM模型的改变,生成迁移脚本
#3.flask db upgrade:

3.3静态模板渲染

主要就是静态html改为jianjia2的模式,这里action的href=“#”,不然出现问题。然后在蓝图中设置路由和页面,
auth.py,这里设置了注册的路由和页面

from flask import Blueprint,render_template
# /auth
bp=Blueprint("auth",__name__,url_prefix="/auth")
@bp.route("/regist/")
def regist():
    return render_template("regist.html")

3.4使用flask-mail邮箱验证

3.4.1邮箱发送服务搭建与测试

pip install flask-mail

进行邮箱smtp协议验证,设置邮箱服务器。然后去config进行邮箱信息设置。

MAIL_SERVER="smtp.qq.com"
MAIL_USE_SSL=True
MAIL_PORT=465
MAIL_USERNAME="xxx"
MAIL_PASSWORD="xxx"#smtp协议授权密码
MAIL_DEFAULT_SENDER="xxx"

在exts.py中引入mail

from flask_mail import Mail
mail=Mail()

在app中进行导入与绑定

mail.init_app(app)

在auth中设置路由进行测试

from flask_mail import Message
from exts import mail
@bp.route("/mail/test/")
def mail_test():
    message=Message(subject="邮箱测试",recipients=["18xxxx8@163.com"],body="这是一条测试邮件")
    mail.send(message)
    return "邮件发送成功"

运行,进行测试,我成功收到了验证信息

3.4.2邮箱发送验证

1.首先用变量传参的方式,设置路由和蓝图auth

@bp.route("/captcha/email/")
def get_email_captcha():
    email=request.args.get("email")#?变量传递的方式传入参数email
    source=string.digits*6
    captcha=random.sample(source,6)
    captcha=''.join(captcha)
    message=Message(subject="注册验证码",recipients=[email],body=f"您的验证码是:{captcha}")
    mail.send(message)
    return "success"

进入网址http://192.168.3.76:5000/auth/captcha/email?email=xxx@163.com进行测试。
2.将邮箱和验证码存储到数据库表中,因此在models中创建一个model

class EmailCaptchaModel(db.Model):
    __tablename__="email_captcha"
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)
    email=db.Column(db.String(100),nullable=False)
    captcha=db.Column(db.String(100),nullable=False)

然后将表映射到数据库中

flask db migrate
flask db upgrade

然后再auth蓝图中,将数据实例化到数据库中

from exts import db
from models import EmailCaptchaModel
email_captcha=EmailCaptchaModel(email=email,captcha=captcha)
db.session.add(email_captcha)
db.session.commit()

并且用ajax请求,所以返回数据格式化为js格式

from flask import jsonify
return jsonify({"code":200,"message":"","data":None})

3.前端按下获取验证码按钮,通过js,获取到邮箱,然后向服务端发送一个请求,然后就是上面的后端运行代码。用到了jquery。regist.js:

//整个网页加载完成后再执行
$(function(){
    $("#captcha-btn").click(function(event){
        event.preventDefault();//组织默认的实践
        var email=$("input[name='email']").val();//通过name从input中获取用户输入的val
        $.ajax({
            url:"/auth/captcha/email?email="+email,
            method:"GET",
            success:function(result){
                var code=result['code'];
                if (code==200){alert("邮箱验证码发送成功");}
                else{alert(result['message']);}
            },
            fail:function(error){console.log(error);}
        })
    });
});

3.5使用flask-wtf表单验证

pip install flask-wtf
pip install email_validator

蓝图文件夹里面建一个forms.py写一个注册表单前端验证

import wtforms
from wtforms.validators import Email,Length,EqualTo
from models import UserModel,EmailCaptchaModel
from exts import db
#Form:验证前端提交的数据是否符合要求
class RegisterForm(wtforms.Form):
    email=wtforms.StringField(validators=[Email(message="邮箱格式错误")])
    captcha=wtforms.StringField(validators=[Length(min=6,max=6,message="验证码格式错误")])
    username=wtforms.StringField(validators=[Length(min=3,max=20,message="用户名格式错误")])
    password=wtforms.StringField(validators=[Length(min=6,max=20,message="密码格式错误")])
    password_confirm=wtforms.StringField(validators=[EqualTo("password",message="密码不一致")])
    #自定义验证1:邮箱是否已经注册
    def validate_email(self,field):
        email=field.data
        user=UserModel.query.filter_by(email=email).first()
        if user:
            raise wtforms.ValidationError(message="该邮箱已经被注册")
    #2:验证码是否正确
    def validate_captcha(self,field):
        captcha=field.data
        email=self.email.data
        captcha_model=EmailCaptchaModel.query.filter_by(email=email,captcha=captcha).first()
        if not captcha_model:
            raise wtforms.ValidationError(message="验证码错误")
        else:
            db.session.delete(captcha_model)
            db.session.commit()

3.6登录页面

1.首先是把静态的login.html改为flask格式的;
2.然后在form.py里面利用wtforms.Form对提交来的表单进行前端格式验证;
3.通过post提交来的表单进行验证,并保存此登陆者的cookie

@bp.route("/login/",methods=['GET','POST'])
def login():
    if request.method=='GET':
        return render_template('login.html')
    else:
        form=LoginForm(request.form)
        if form.validate():
            email=form.email.data
            password=form.password.data
            user=UserModel.query.filter_by(email=email).first()
            if not user:
                print("用户邮箱未注册")
                return redirect(url_for("auth.login"))
            if check_password_hash(user.password,password):
                #cookie,flask中的session,经过加密存储到cookie中
                session['user_id']=user.id
                return redirect("/")
            else:
                print("密码错误")
                return redirect(url_for("auth.login"))
        else:
            print(form.errors)
            return redirect(url_for("auth.login"))

3.通过钩子函数(befor_request/before_first_request/after_request),保存用户cookie到一个全局对象上,并利用上下文处理钩子(context_processor)将数据显示到前端。

@app.before_request
def my_before_request():
    user_id=session.get(user_id)
    if user_id :
        user=UserModel.query.get(user_id)
        setattr(g,"user",user)
    else:
        setattr(g,"user",None)
#上下文处理器的钩子
@app.context_processor
def my_context_processor():
    return {"user":g.user}

4.在base.html中将钩子拿到的user显示到前端,并写一个logout路由蓝图

{% if user %}
<li><a >{{ user.username }}</a></li>
<li><a href="{{url_for('auth.logout')}}">注销</a></li>
{% else %}
<li><a href="{{url_for('auth.login')}}">登录</a></li>
<li><a href="{{url_for('auth.regist')}}">注册</a></li>
{% endif %}
@bp.route('/logout/')
def logout():
    session.clear()
    return redirect('/')

3.7发布问答页面

1.首先是把静态的question.html改为flask格式的,然后在蓝图中设置路由,当get请求时,就render这个html文件。
2.post发布的内容也要通过form表单提交的方式保存到数据库中,所以在models中需要建对象表,并且有外键和反向引用的关系表

class QuestionModel(db.Model):
    __tablename__="question"
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)
    title=db.Column(db.String(100),nullable=False)
    content=db.Column(db.Text,nullable=False)
    create_time=db.Column(db.DateTime,default=datetime.now)
    #外键
    author_id=db.Column(db.Integer,db.ForeignKey("user.id"))
    author=db.relationship(UserModel,backref="questions")

3.post提交表单的话,也需要表单前端先验证,所以需要在forms.py中进行验证。

class QuestionForm(wtforms.Form):
    title=wtforms.StringField(validators=[Length(min=3,max=100,message="标题格式错误")])
    content=wtforms.StringField(validators=[Length(min=3,message="内容格式错误")])

4.在qa.py中设置路由和蓝图,对post拿来的form进行验证并存到数据库中。

@bp.route("/qa/public/",methods=['GET','POST'])
def public_question():
    if request.method=='GET':
        return render_template("question.html")
    else:
        form=QuestionForm(request.form)
        if form.validate():
            title=form.title.data
            content=form.content.data
            question=QuestionModel(title=title,content=content,author=g.user)
            db.session.add(question)
            db.session.commit()
            return redirect("/")
        else:
            print(form.errors)
            return redirect(url_for("qa.public_question"))

5.新建一个decorators.py文件,设置一个登陆装饰器,当用户没有登录时,就不可以访问问答这个页面。

from flask import g,redirect,url_for
from functools import wraps
def login_required(func):
    @wraps(func)#保留func信息
    def inner(*args,**kwargs):#万能参数:位置参数*args(1,2,3);关键字参数**kwargs(d=4,e=5)
        if g.user:
            return func(*args,**kwargs)
        else:
            return redirect(url_for("auth.login"))
    return inner

3.8问答列表显示页面

1.首先是把静态的index.html改为flask格式的,然后在蓝图中设置路由,当get请求时,就render这个html文件。
2.当点击列表标题时跳入到列表详情内容的页面,所以需要写路由蓝图,跳到detail.html

3.9评论相关内容

1.首先评论需要入库,所以先建Model,这里用了两个外键。

class AnswerModel(db.Model):
    __tablename__="answer"
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)
    content=db.Column(db.Text,nullable=False)
    create_time=db.Column(db.DateTime,default=datetime.now)
    #外键
    question_id=db.Column(db.Integer,db.ForeignKey("question.id"))
    author_id=db.Column(db.Integer,db.ForeignKey("user.id"))
    #关系
    question=db.relationship(QuestionModel,backref=db.backref("answers",order_by=create_time.desc()))
    author=db.relationship(UserModel,backref="answers")

2.表单前端先验证,所以需要在forms.py中进行验证。

class AnswerForm(wtforms.Form):
    content=wtforms.StringField(validators=[Length(min=3,message="标题格式错误")])
    question_id=wtforms.StringField(validators=[InputRequired(message="必须要传入问题id")])

3.路由蓝图

@bp.post("/answer/public/")
@login_required
def public_answer():
    form=AnswerForm(request.form)
    if form.validate():
        content=form.content.data
        question_id=form.question_id.data
        answer=AnswerModel(content=content,question_id=question_id,author=g.user.id)
        db.session.add(answer)
        db.session.commit()
        return redirect(url_for("qa_detail",question_id=question_id))
    else:
        print(form.errors)
        return redirect(url_for("qa_detail",question_id=request.form.get("question_id")))

4.前端,表单提交和跳转的页面。
5.搜索问答功能的实现:写一个search路由蓝图,然后在base模板里,把search地址给search按钮的跳转链接,就实现了按下这个按钮实现search功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是小z呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值