Flask-bootstrap,flask-wtf,flask-sqlalchemy

flask-bootstrap 初始化,就可以使用一个包含所有Bootstrap文件的基模板,利用jinja2的模板继承机制,可以扩展一个具有基本页面结构的基模板。

from flask import Flask, render_template
from flask_bootstrap import Bootstrap

app = Flask(__name__)
bootstrap = Bootstrap(app)


@app.route('/')
def hello_world():
    return render_template('index.html')


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

很多块都是Flask-Bootstrap 自用的,如果直接重定义可能会导致一些问题。例如,Bootstrap 所需的文件在styles 和scripts 块中声明。如果程序需要向已经有内容的块中添加新内容,必须使用Jinja2 提供的super() 函数。例如,如果要在衍生模板中添加新的JavaScript 文件,需要这么定义scripts 块:

{% block scripts %}
{{ super() }}
<script type="text/javascript" src="my-script.js"></script>
{% endblock %}

flask-wtf提供了表单验证的方法,
表单类型(StringField, PasswordField, SubmitField, FileField)
验证表单(DataRequired, Length, Email, Regexp, EqualTo)

from flask_wtf import FlaskForm
# 确定表单的类型, 相当于input标签中type的作用
from wtforms import StringField, PasswordField, SubmitField, FileField
# 确保表单内容是否合法;
from wtforms.validators import DataRequired, Length, Email, Regexp, EqualTo

from flask_wtf.file import FileRequired, FileAllowed


# Regexp == regular experssion (用于编写正则表达式的)
class LoginForm(FlaskForm):
    user = StringField(
        label="用户名/手机/邮箱",
        validators=[
            DataRequired(message="用户名不能为空"),
            Length(5, 12),
        ]
    )
    passwd = PasswordField(
        label="密码",
        validators=[
            Length(6)
        ]
    )
    submit = SubmitField(
        label="登录"

    )


class RegisterForm(FlaskForm):
    user = StringField(
        label="用户名/手机/邮箱",
        validators=[
            Length(5, 12),
        ]
    )
    email = StringField(
        label="邮箱",
        validators=[
            Email("邮箱格式不正确!")
        ]
    )
    phone = StringField(
        label="电话",
        validators=[
            Regexp(r'1\d{10}', message="手机格式不正确!")
        ]
    )
    passwd = PasswordField(
        label="密码",
        validators=[
            Length(6)
        ]
    )

    repasswd = PasswordField(
        label="确认密码",
        validators=[
            EqualTo('passwd', "两次密码不一致!")
        ]

    )

    # 用户头像
    # <input type="file" >
    face = FileField(
        label="上传头像",
        validators=[
            FileAllowed(['png', 'jpg'], message="文件非图片")
        ]
    )
    submit = SubmitField(
        label="注册"

    )

flask-sqlalchemy 提供了数据库支持的扩展,可参考http://www.pythondoc.com/flask-sqlalchemy/
Flask-SQLAlchemy 扩展配置键:SQLALCHEMY_DATABASE_URI用于连接数据的数据库,连接mysql数据库使用mysql://username:password@server/db,默认情况下需要导入MySQLdb模块,可以通过mysql+pymysql://username:password@server/db修改

from datetime import datetime
import time
import pymysql
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
from sqlalchemy import desc

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:hello@localhost/User'
# SQLAlchemy 将会追踪对象的修改并且发送信号。
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
app.config['SECRET_KEY'] = 'hello'
boostrap = Bootstrap(app)


# 默认情况下创建一个表, 表名为类名; 如果指定了__tablename__, 那么表名为你指定的名称;


class Student(db.Model):
    __tablename__ = "students"
    # sid: 表头的一列, db.SMALLINT代表存储的数据类型, primary_key(主键), 数据是唯一的;
    sid = db.Column(db.SMALLINT, primary_key=True)
    sname = db.Column(db.String(50))
    sage = db.Column(db.SMALLINT)


#  实现一对多(Role(1): User(n))的关系
#   - 多的一端写外键
#   - 少的一端写反向引用
class User(db.Model):
    # autoincrement=True自增
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    #  unique=True, name的值不能重复, 是唯一的;
    name = db.Column(db.String(50), unique=True)
    # 长度为100, 是因为网站密码一般会加密;
    passwd = db.Column(db.String(100))
    # 指定用户注册/创建的时间,
    # default, 指定默认值, datetime.now()获取当前时间;
    # 用户注册时间为当前时间;
    add_time = db.Column(db.DateTime, default=datetime.now())
    gender = db.Column(db.Boolean, default=True)
    # 用户的角色id,不能随便写, 必须要关联其他的数据库表(role) --- 外键
    role_id = db.Column(db.INTEGER, db.ForeignKey('role.id'))

    def __repr__(self):
        return '<User:%s>' % (self.name)


# 用户角色表
class Role(db.Model):
    # autoincrement=True自增
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    #  unique=True, name的值不能重复, 是唯一的;
    name = db.Column(db.String(50), unique=True)
    #  Role表中的users属性与User表关联, 并且User这个表中可以由role这个对象属性;
    users = db.relationship('User', backref='role')

    # 对象的字符串显示, 方便查询时使用
    def __repr__(self):
        return "<Role:%s>" % (self.name)


if __name__ == '__main__':
    # 1. 创建定义的表结构
    db.create_all()
    # 2. 删除定义的表结构
    # db.drop_all()

向表中插入数据

role1 = Role(name="超级会员")
role2 = Role(name="会员")
db.session.add(role1)
db.session.add(role2)
db.session.commit()

查询数据

print(Role.query.all())

根据条件查询,筛选数据(filter_by)

###slect * from table where xxx=xxx;
print(User.query.filter_by(role_id=1).all())

对于找到的内容进行更新

u = User.query.filter_by(name='user1').first()
print(u)
u.passwd = '123456'
db.session.add(u)
db.session.commit()

筛选数据方法2,通过这种方式可以查看原生的sql语句

user = User.query.filter(User.role_id==1)
print(user)

对于查询的信息可以进行限制

users = User.query.filter_by(role_id=1).limit(5).all()
print(users, len(users), end='\n')

此时输出前5条信息,排序输出,对于查询的信息进行排序输出(默认情况由小到大进行排序), 如果想要由大到小: desc(User.add_time);

users = User.query.filter_by(role_id=1).order_by(desc(User.add_time)).all()
print(users)

多个过滤函数加一个显示函数

users = User.query.filter_by(role_id=1).order_by(desc(User.add_time)).limit(5).offset(2).all()

offset指定偏移量,limit指定输出数量,类似于切片操作
分页操作

users = User.query.paginate(1, 5)
print(users.items)

分页操作中,第一个参数代表显示第几页的数据, 第二个参数代表每页显示多少条数据。

发布了80 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/C_abua/article/details/83660396