輕量級Web框架Flask(二)

2023-04-15 06:00:34

Flask-SQLAlchemy

MySQL是免費開源軟體,大家可以自行搜尋其官網(https://www.MySQL.com/downloads/)

測試MySQL是否安裝成功

在所有程式中,找到MySQL→MySQL Server 5.6下面的命令列工具,然後單擊輸入密碼後回車,就可以知道MySQL資料庫是否連結成功。

右擊桌面上的「計算機」,在彈出的快捷鍵選單中選擇「屬性」|「高階系統設定」|「環境變數」,在path裡面新增MySQL bin目錄的路徑。選擇環境變數,在環境變數中的path路徑下輸入你的MySQL路徑就行了。預設安裝的路徑是C:\MySQL\MySQL Server 5.6\bin

安裝flask-sqlalchemy,安裝不了就更換豆瓣源

pip install flask-sqlalchemy

 物件-關係對映實質

class  Lib_card(db.Model):
    __tablename__ = 'lib_card'
    id = db.Column(db.Integer, primary_key=True, comment='id號')
    card_id = db.Column(db.Integer, nullable=False, comment = '借書證')
    book_id = db.Column(db.Integer, db.ForeignKey('book.id'))
    books = db.relationship('Book', backref=db.backref('cards'),uselist=False)

在Flask-SQLAlchemy中,插入、修改、刪除操作均由資料庫對談管理

需要一個設定config.py

USERNAME= 'root'                                        #設定登入賬號
PASSWORD= '930103'                                        #設定登入密碼
HOST= '127.0.0.1'                                        #設定主機地址
PORT= '3306'                                                #設定埠號
DATABASE= 'demo1'                                #設定存取的資料庫
SQLALCHEMY_DATABASE_URI= f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DATABASE}'#建立資料庫連線範例
#動態追蹤修改設定,如未設定只會提示警告
SQLALCHEMY_TRACK_MODIFICATIONS=False
#查詢時會顯示原始SQL語句
SQLALCHEMY_ECHO= True

範例

from datetime import datetime

from flask import Flask                                                        #匯入Flask模組
from flask_sqlalchemy import SQLAlchemy               #匯入SQLAlchemy模組
import config                                                                 #匯入組態檔
app= Flask(__name__)                                                        #Flask初始化
app.config.from_object(config)                                        #組態檔範例化
#初始化一個物件
db=SQLAlchemy(app)

class Book(db.Model):
    __tablename__ = 'book'
    id = db.Column(db.Integer, primary_key = True,comment='id號')
    title = db.Column(db.String(50), nullable=False,comment='書名')
    publishing_office = db.Column(db.String(100), nullable=False,comment='出版社')
    isbn = db.Column(db.String(100), nullable=False, comment='isbn號')
    storage_time = db.Column(db.DateTime, default=datetime.now(), comment='入庫時間')

class  Lib_card(db.Model):
    __tablename__ = 'lib_card'
    id = db.Column(db.Integer, primary_key=True, comment='id號')
    card_id = db.Column(db.Integer, nullable=False, comment = '借書證')
    book_id = db.Column(db.Integer, db.ForeignKey('book.id'))
    books = db.relationship('Book', backref=db.backref('cards'),uselist=False)

with app.app_context():
#測試資料庫連線是否成功
    db.create_all()     #建立資料庫
    # book1= Book(id=9,title='智慧導論', publishing_office='高等教育出版社',isbn='9787040479844')
    # db.session.add(book1)
    # db.session.commit()
    # result = Book.query.filter(Book.id == 9).first()
    # print(result.title)
    # agine = Book.query.filter(Book.title == result.title).all()
    # for i in agine:
    #     print(i.id)
    # db.session.delete(result)
    # db.session.commit()
    # card1=Lib_card(card_id='18001', book_id='8')
    # card2=Lib_card(card_id='18002', book_id='8')
    # db.session.add(card1)
    # db.session.add(card2)
    # db.session.commit()
    book_query = Book.query.filter(Book.id == 9).first()
    lib_card_query = book_query.cards
    for i in lib_card_query:
        print(i.card_id)

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

# if __name__== '__main__':
#     app.run(debug=True)

注意:一個表(模型)的定義必須要定義一個主鍵,這個主鍵一般為id。在定義了Lib_card類後,申明瞭一個外來鍵,並且在relationship方法中使用uselist=False來約束其關係。book_id =db.Column(db.Integer,db.ForeignKey('book.id'))表示建立一個外來鍵,型別要跟主表一樣,通過db.ForeignKey("user.id")與主表繫結books =db.relationship('Book',backref=db.backref('cards');uselist=False)表示Book可以根據Lib_card中的借書證查詢到book表中的資訊,backref="cards"表示book表可以直接通過cards查詢到該書下的借書證號碼。

框架範例

建一個apps資料夾,新增一個admin包,admin包下建立三個py檔案

#__init__.py
#預載入模組內容
#其他地方呼叫的時候 可以直接from apps.admin import bp as admin_bp不用找到views
from .views import bp
#forms.py
from flask_wtf import FlaskForm
from wtforms import *
from wtforms.validators import *

class NameForm(FlaskForm):
    username = StringField('使用者名稱',validators=[DataRequired()])
    password = PasswordField('密碼',validators=[DataRequired()])
    submit = SubmitField('提交')
#models.py
from exts import db

class User(db.Model):
    __tablename__ = 'jq_user'
    uid = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), nullable=False, comment="使用者名稱")
    password = db.Column(db.String(100), nullable=False,comment="密碼")
    email = db.Column(db.String(50), nullable=False, unique=True, comment = "郵箱")
#views.py
from flask import Blueprint, request, flash, render_template
from apps.admin.forms import NameForm
from apps.admin.models import User

bp = Blueprint("admin",__name__)

@bp.route("/admin",methods=['GET','POST'])
def index():
    form = NameForm()
    if request.method == 'POST':
        if form.validate_on_submit():
            username = request.form.get('username')
            password = request.form.get('password')
            result = User.query.filter(User.username==username).first()
            if result and password == result.password:
                flash('登入成功')
            else:
                return render_template('login.html', form=form, errormsg="登陸失敗")
    return render_template('login.html', form=form)

建一個資料夾templates,專門放login.html檔案,通過render_template呼叫

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <h1>使用者註冊登入</h1>
    <form method="post" action="/test/admin">
        {{ form.csrf_token()}}
        {{ form.username.label }}{{ form.username}}
        {{ form.password.label }}{{ form.password}}
        {{ form.submit }}{{errormsg}}

        {% for message in get_flashed_messages() %}
            {{ message }}
        {% endfor %}
    </form>
</head>
<body>

</body>
</html>

建一個app.py

from flask import Flask
from apps.admin import bp as admin_bp
from exts import db
from apps.common import bp as common_bp
from apps.front import bp as front_bp
from apps.admin.models import User
from apps.common.models import Book


def create_app():
    app = Flask(__name__)
    app.secret_key = '123321'
    #註冊藍圖,註冊時候可以設定字首
    app.register_blueprint(admin_bp,url_prefix="/test")
    app.register_blueprint(common_bp)
    app.register_blueprint(front_bp)
    app.config.from_object('config')
    # db.app = app
    db.init_app(app)
    return app



if __name__ == '__main__':
    app = create_app()
    with app.app_context():
        db.create_all()
    app.run(host="127.0.0.1",port=1314,debug=True)

建一個config.py

DEBUG=True
USERNAME= 'root'                                        #設定登入賬號
PASSWORD= '930103'                                        #設定登入密碼
HOST= '127.0.0.1'                                        #設定主機地址
PORT= '3306'                                                #設定埠號
DATABASE= 'demo1'                                #設定存取的資料庫
SQLALCHEMY_DATABASE_URI= f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DATABASE}'#建立資料庫連線範例
#動態追蹤修改設定,如未設定只會提示警告
SQLALCHEMY_TRACK_MODIFICATIONS=False
#查詢時會顯示原始SQL語句
SQLALCHEMY_ECHO= True

建一個exts.py

#encoding:utf-8
from flask_sqlalchemy import SQLAlchemy
db=SQLAlchemy()