24. Flask 自定義模型類

自定義模型類

本篇章介紹Flask自定義模型類的概念,以及寫一個(gè)快速入門的示例,基本內(nèi)容如下:

  • 定義兩個(gè)模型類,并創(chuàng)建數(shù)據(jù)庫表
  • 創(chuàng)建數(shù)據(jù),寫入數(shù)據(jù)庫
  • 編寫模板以及視圖函數(shù),在頁面展示數(shù)據(jù)

定義模型

模型表示程序使用的數(shù)據(jù)實(shí)體,在Flask-SQLAlchemy中,模型一般是Python類,繼承自db.Model,db是SQLAlchemy類的實(shí)例,代表程序使用的數(shù)據(jù)庫。

類中的屬性對應(yīng)數(shù)據(jù)庫表中的列。id為主鍵,是由Flask-SQLAlchemy管理。db.Column類構(gòu)造函數(shù)的第一個(gè)參數(shù)是數(shù)據(jù)庫列和模型屬性類型。

如下示例:定義了兩個(gè)模型類,作者和書名。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql
pymysql.install_as_MySQLdb()

app = Flask(__name__)

class Config(object):
    """配置參數(shù)"""
    # 設(shè)置連接數(shù)據(jù)庫的URL
    user = 'root'
    password = '*********'
    database = 'flask_ex'
    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://%s:%s@127.0.0.1:3306/%s' % (user,password,database)

    # 設(shè)置sqlalchemy自動(dòng)更跟蹤數(shù)據(jù)庫
    SQLALCHEMY_TRACK_MODIFICATIONS = True

    # 查詢時(shí)會(huì)顯示原始SQL語句
    # app.config['SQLALCHEMY_ECHO'] = True

    # 禁止自動(dòng)提交數(shù)據(jù)處理
    app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = False

# 讀取配置
app.config.from_object(Config)

# 創(chuàng)建數(shù)據(jù)庫sqlalchemy工具對象
db = SQLAlchemy(app)

#定義模型類-作者
class Author(db.Model):
    __tablename__ = 'author'
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(32),unique=True)
    email = db.Column(db.String(64))
    au_book = db.relationship('Book',backref='author')
    def __str__(self):
        return 'Author:%s' %self.name

#定義模型類-書名
class Book(db.Model):
    __tablename__ = 'books'
    id = db.Column(db.Integer,primary_key=True)
    info = db.Column(db.String(32),unique=True)
    leader = db.Column(db.String(32))
    au_book = db.Column(db.Integer,db.ForeignKey('author.id'))
    def __str__(self):
        return 'Book:%s,%s'%(self.info,self.lead)


if __name__ == '__main__':

    # 刪除所有表
    db.drop_all()

    # 創(chuàng)建所有表
    db.create_all()

執(zhí)行腳本之后,到mysql中查看表結(jié)構(gòu)如下。

創(chuàng)建表 db.create_all()

mysql> show tables;
+--------------------+
| Tables_in_flask_ex |
+--------------------+
| author             |
| books              |
+--------------------+
4 rows in set (0.00 sec)

mysql> 

查看author表結(jié)構(gòu) desc author

mysql> desc author;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(32) | YES  | UNI | NULL    |                |
| email | varchar(64) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

查看books表結(jié)構(gòu) desc books

mysql> desc books;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| info    | varchar(32) | YES  | UNI | NULL    |                |
| leader  | varchar(32) | YES  |     | NULL    |                |
| au_book | int(11)     | YES  | MUL | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

創(chuàng)建數(shù)據(jù)

...
if __name__ == '__main__':

    # 生成數(shù)據(jù)
    author_1 = Author(name='我吃西紅柿', email='xihongshi@163.com')
    author_2 = Author(name='蕭潛', email='xiaoqian@126.com')
    author_3 = Author(name='唐家三少', email='sanshao@163.com')
    book_1 = Book(info='吞噬星空', leader='羅峰')
    book_2 = Book(info='寸芒', leader='李楊')
    book_3 = Book(info='飄渺之旅', leader='李強(qiáng)')
    book_4 = Book(info='冰火魔廚', leader='融念冰')
    # 把數(shù)據(jù)提交給用戶會(huì)話
    db.session.add_all([author_1, author_2, author_3, book_1, book_2, book_3, book_4])
    # 提交會(huì)話
    db.session.commit()

在main方法下創(chuàng)建多個(gè)作者以及書本的數(shù)據(jù),執(zhí)行腳本后,查看mysql數(shù)據(jù),如下:

mysql> select * from author;
+----+-----------------+-------------------+
| id | name            | email             |
+----+-----------------+-------------------+
|  1 | 我吃西紅柿      | xihongshi@163.com |
|  2 | 蕭潛            | xiaoqian@126.com  |
|  3 | 唐家三少        | sanshao@163.com   |
+----+-----------------+-------------------+
3 rows in set (0.00 sec)

mysql> select * from books;
+----+--------------+-----------+---------+
| id | info         | leader    | au_book |
+----+--------------+-----------+---------+
|  1 | 吞噬星空     | 羅峰      |    NULL |
|  2 | 寸芒         | 李楊      |    NULL |
|  3 | 飄渺之旅     | 李強(qiáng)      |    NULL |
|  4 | 冰火魔廚     | 融念冰    |    NULL |
+----+--------------+-----------+---------+
4 rows in set (0.00 sec)

mysql> 

使用 flask_wtf 編寫視圖函數(shù)的表單

1.編寫完整flask應(yīng)用,包含視圖函數(shù)

from flask import Flask,render_template,url_for,redirect,request
from flask_sqlalchemy import SQLAlchemy
import pymysql
pymysql.install_as_MySQLdb()
# 導(dǎo)入Flask-WTF表單
from flask_wtf import FlaskForm
# 導(dǎo)入表單所需要的字段類型
from wtforms import StringField, PasswordField, SubmitField
# 導(dǎo)入表單的驗(yàn)證器
from wtforms.validators import DataRequired, EqualTo
# 啟動(dòng)命令的管理類
from flask_script import Manager   

app = Flask(__name__)

class Config(object):
    """配置參數(shù)"""
    # 設(shè)置連接數(shù)據(jù)庫的URL
    user = 'root'
    password = '*************'
    database = 'flask_ex'
    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://%s:%s@127.0.0.1:3306/%s' % (user,password,database)

    # 設(shè)置sqlalchemy自動(dòng)更跟蹤數(shù)據(jù)庫
    SQLALCHEMY_TRACK_MODIFICATIONS = True

    # 查詢時(shí)會(huì)顯示原始SQL語句
    # app.config['SQLALCHEMY_ECHO'] = True

    # 禁止自動(dòng)提交數(shù)據(jù)處理
    app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = False

    # 設(shè)置密鑰,用于csrf_token的加解密
    app.config["SECRET_KEY"] = "xhosd6f982yfhowefy29f"

# 讀取配置
app.config.from_object(Config)

# 創(chuàng)建數(shù)據(jù)庫sqlalchemy工具對象
db = SQLAlchemy(app)

#定義模型類-作者
class Author(db.Model):
    __tablename__ = 'author'
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(32),unique=True)
    email = db.Column(db.String(64))
    au_book = db.relationship('Book',backref='author')
    def __str__(self):
        return 'Author:%s' %self.name


#定義模型類-書名
class Book(db.Model):
    __tablename__ = 'books'
    id = db.Column(db.Integer,primary_key=True)
    info = db.Column(db.String(32),unique=True)
    leader = db.Column(db.String(32))
    au_book = db.Column(db.Integer,db.ForeignKey('author.id'))
    def __str__(self):
        return 'Book:%s,%s'%(self.info,self.leader)


# 定義表單的模型類,用來添加書本以及作者數(shù)據(jù)
class AddAuthorBook(FlaskForm):
    """自定義的注冊表單模型類"""
    # DataRequired 保證數(shù)據(jù)必須填寫,并且不能為空
    author_name = StringField(label="作者名稱", validators=[DataRequired("作者名稱不能為空")]) #  參數(shù):名字,驗(yàn)證器列表
    book_info = StringField(label="書本信息", validators=[DataRequired("書本信息不能為空")])
    submit = SubmitField(label="添加")

@app.route('/',methods=['GET','POST'])
def index():
    #查詢所有作者和書名信息
    authors = Author.query.all()
    books = Book.query.all()
    #創(chuàng)建表單對象
    form = AddAuthorBook()
    if form.validate_on_submit():
        #獲取表單輸入數(shù)據(jù)
        author_name = form.author_name.data
        book_info = form.book_info.data
        #把表單數(shù)據(jù)存入模型類
        db_author = Author(name=author_name)
        db_book = Book(info=book_info)
        db_book.leader = author_name
        db_book.au_book = db_author.id
        #提交會(huì)話
        db.session.add_all([db_author,db_book])
        db.session.commit()

        #添加數(shù)據(jù)后,再次查詢所有作者和書名信息
        authors = Author.query.all()
        books = Book.query.all()
        return render_template('index.html',author=authors,book=books,form=form)
    else:
        if request.method=='GET':
            render_template('index.html', author=authors, book=books,form=form)
    return render_template('index.html',author=authors,book=books,form=form)

#刪除作者
@app.route('/delete_author<id>')
def delete_author(id):
    print('delete author id = %s' % id)
    #精確查詢需要?jiǎng)h除的作者id
    author = Author.query.get(id)
    db.session.delete(author)
    db.session.commit()
    #直接重定向到index視圖函數(shù)
    return redirect(url_for('index'))

#刪除書名
@app.route('/delete_book<id>')
def delete_book(id):
    print('delete book id = %s' % id)
    #精確查詢需要?jiǎng)h除的書名id
    book = Book.query.get(id)
    db.session.delete(book)
    db.session.commit()
    #直接重定向到index視圖函數(shù)
    return redirect(url_for('index'))

if __name__ == '__main__':

    # 創(chuàng)建Manager管理類的對象
    manager = Manager(app)

    # 通過管理對象來啟動(dòng)flask
    manager.run()

2.設(shè)置index.html模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>玄幻系列</h1>
    <form method="post">
        {{ form.csrf_token }}
        <p>作者:{{ form.author_name }}</p>
        <p>書名:{{ form.book_info }}</p>
        <p>{{ form.submit }}</p>
    </form>

    <hr>

    <ul>
        {% for item in author %}
        <li>{{ item }}</li><a href='/delete_author{{ item.id }}'>刪除</a>
        {% endfor %}
    </ul>

    <hr>

    <ul>
        {% for item in book %}
        <li>{{ item }}</li><a href='/delete_book{{ item.id }}'>刪除</a>
        {% endfor %}
    </ul>
</body>
</html>

3.執(zhí)行python3 db_demo2.py runserver啟動(dòng)服務(wù)后,進(jìn)行功能測試

從上面的幾個(gè)示例,基本清楚講解了模型類如何定義,表單如何設(shè)置,模板中如何展示數(shù)據(jù),表單如何提交數(shù)據(jù),數(shù)據(jù)如何設(shè)置刪除等功能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容