Flask實(shí)戰(zhàn)腳手架-用戶模塊

實(shí)戰(zhàn)腳手架準(zhǔn)備分三部曲

Flask實(shí)戰(zhàn)腳手架 (后端+restful api)
Yii2實(shí)戰(zhàn)腳手架 (后端+restful api)
Vue2實(shí)戰(zhàn)腳手架(前端)


Flask實(shí)戰(zhàn)腳手架 (后端+restful api)

學(xué)習(xí)Flask從實(shí)戰(zhàn)開始赤惊,制作一個(gè)web常用的腳手架了赵,已備以后快速開發(fā)污它。
項(xiàng)目git地址第二次提交

暫定功能模塊:

  • 用戶模塊
  • 文章模塊

用到的python插件:

  • Flask-Login #用戶登陸
  • Flask-Migrate #數(shù)據(jù)庫管理工具
  • Flask-DebugToolbar #dubug工具欄
  • Flask-SQLAlchemy #ORM
  • Flask-WTF #表單

用戶模塊

安裝所需的插件
pip install flask-login flask-sqlalchemy flask-migrate flask-wtf

1. 修改 app/__init__.py如下

from flask import Flask
from app.config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager


db = SQLAlchemy()
migrate = Migrate()
login = LoginManager()
login.login_view = "backend.login" #配置用戶默認(rèn)登陸端點(diǎn)


def create_app(config_class=Config):
   app = Flask(__name__)
   app.config.from_object(config_class)

   db.init_app(app)
   migrate.init_app(app, db)
   login.init_app(app)

   from app.backend import bp as backendbp #導(dǎo)入backend藍(lán)圖
   app.register_blueprint(backendbp, url_prefix='/backend') #注冊(cè)藍(lán)圖

   return app

主要是注冊(cè)插件與藍(lán)圖

3. 初始化注冊(cè)后臺(tái)藍(lán)圖app/backend/__init__.py

from flask import Blueprint

bp = Blueprint('backend', __name__)

from . import views

4. 添加用戶登陸表單app/backend/forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired


class LoginForm(FlaskForm):
    username = StringField('username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])
    remember_me = BooleanField('Remember Me')
    submit = SubmitField('Sign In')

4. 添加后臺(tái)路由app/backend/views.py

from . import bp
from flask import render_template, flash, redirect, url_for, request
from app.models import User
from flask_login import login_user, logout_user, login_required
from app.backend.froms import LoginForm


@bp.route('/')
@bp.route('/index')
@login_required
def index():
    return render_template('backend/index.html')


@bp.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user is None or not user.check_password(form.password.data):
            flash('賬號(hào)或密碼錯(cuò)誤,請(qǐng)重新輸入!')
            return redirect(url_for('backend.login'))
        login_user(user)
        next_page = request.args.get('next')
        if next_page:
            return redirect(next_page)
        return redirect(url_for('backend.index'))
    return render_template('backend/login.html', form=form)


@bp.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('backend.index'))

1. 創(chuàng)建模型app/models.py

from app import db, login
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin, login_manager


class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True)
    password_hash = db.Column(db.String(128))
    last_login_at = db.Column(db.DateTime, default=datetime.utcnow)

    profile = db.relationship('Profile', backref='user', lazy='dynamic')

    def __repr__(self):
        return '<User {}>'.format(self.username)

    @property
    def password(self):
        return self.password_hash

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

# 配置用戶登陸時(shí)加載的方法
@login.user_loader
def load_user(user_id):
    return User.query.get(user_id)


class Profile(db.Model):
    __table_args__ = (
        db.PrimaryKeyConstraint('user_id'),
    )

    user_id = db.Column(db.ForeignKey('user.id'))
    nickname = db.Column(db.String(125))
    tel = db.Column(db.String(13))

    def __repr__(self):
        return '<Profile {}, {}>'.format(self.user_id, self.nickname)

好了拘领,到這里哲银,現(xiàn)在可以用flask-migrate數(shù)據(jù)遷移工具初始化數(shù)據(jù)庫,并生成了

flask db init # 第一次需要初始化,以后就不需要此命令了
flask db migrage
flask db upgrade

現(xiàn)在應(yīng)該在項(xiàng)目的根目錄生成app.db的SQLite數(shù)據(jù)庫了
我們來驗(yàn)證下程序是否有問題词顾。我們?cè)趓un.py里面壓入U(xiǎn)ser炸裆、Profile兩表垃它,去試試命令行執(zhí)行

from app import create_app, cli, db
from app.models import User, Profile

app = create_app()
cli.register(app)

@app.shell_context_processor
def make_shell_context():
    return {
        'app': app,
        'User': User,
        'Profile': Profile,
        'DB': db
    }

這里壓入了db與兩表

flask shell # 進(jìn)入shell交互模式
>>> DB
<SQLAlchemy engine=sqlite:////Users/jydd/python/myapp/app.db>
>>> u1 = User(username='user1')
>>> u1.password = '123456'
>>> p1 = Profile(nickname='nickname1', tel='1808888888')
>>> p1.user = u1
>>> p1.user
<User user1>
>>> u2 = User(username='user2')
>>> u2.password = '123456'
>>> u2.check_password('123456')
True
>>> p2 = Profile(nickname='nickname2', tel='19099999999')
>>> p2.user = u2
>>> DB.session.add(u1)
>>> DB.session.commit()
>>> u1.id
1
>>> u1.profile.first().nickname
'nickname1'
>>> DB.session.add(u2)
>>> DB.session.commit()
>>> u2.id
2

5. 模板部分 就不講了,簡(jiǎn)單的標(biāo)簽,直接可以看git項(xiàng)目地址查看源碼

現(xiàn)在通過訪問路由 http://127.0.0.1:5000/backend/
會(huì)跳轉(zhuǎn)到 http://127.0.0.1:5000/backend/login?next=%2Fbackend%2F
登陸成功后會(huì)跳轉(zhuǎn)到 http://127.0.0.1:5000/backend/

backend/login
backend/index
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末国拇,一起剝皮案震驚了整個(gè)濱河市洛史,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酱吝,老刑警劉巖也殖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異务热,居然都是意外死亡忆嗜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門崎岂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捆毫,“玉大人,你說我怎么就攤上這事冲甘《沉В” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵损合,是天一觀的道長(zhǎng)省艳。 經(jīng)常有香客問我,道長(zhǎng)嫁审,這世上最難降的妖魔是什么跋炕? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮律适,結(jié)果婚禮上辐烂,老公的妹妹穿的比我還像新娘。我一直安慰自己捂贿,他們只是感情好纠修,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著厂僧,像睡著了一般扣草。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颜屠,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天辰妙,我揣著相機(jī)與錄音,去河邊找鬼甫窟。 笑死密浑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的粗井。 我是一名探鬼主播尔破,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼街图,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了懒构?” 一聲冷哼從身側(cè)響起餐济,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎痴脾,沒想到半個(gè)月后颤介,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梳星,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赞赖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冤灾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片前域。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖韵吨,靈堂內(nèi)的尸體忽然破棺而出匿垄,到底是詐尸還是另有隱情,我是刑警寧澤归粉,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布椿疗,位于F島的核電站,受9級(jí)特大地震影響糠悼,放射性物質(zhì)發(fā)生泄漏届榄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一倔喂、第九天 我趴在偏房一處隱蔽的房頂上張望铝条。 院中可真熱鬧,春花似錦席噩、人聲如沸班缰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽埠忘。三九已至,卻和暖如春馒索,著一層夾襖步出監(jiān)牢的瞬間给梅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國打工双揪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留动羽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓渔期,卻偏偏與公主長(zhǎng)得像运吓,于是被迫代替她去往敵國和親渴邦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 幾年前買過一套余華的長(zhǎng)篇小說小說《活著》《許三觀賣血記》《兄弟》《在細(xì)雨中呼喊》,作家出版社倦青,漆黑的封面上白色的標(biāo)...
    唐門大少閱讀 885評(píng)論 2 6
  • 海豚是國家保護(hù)動(dòng)物,海豚也是一種比較有靈性的動(dòng)物癣亚,和人類是好朋友丑掺,當(dāng)然海豚也很可愛。 然而今天凌晨形象大使李冰冰在...
    神奇大狗仔閱讀 228評(píng)論 0 0
  • 世間上有種傷痛述雾,比死亡更縈繞于心街州。 它是不告而別。 記得在兩年前的三月八號(hào)玻孟,白晝開啟時(shí)唆缴,有一則消息在朋友圈持續(xù)刷屏...
    幺微閱讀 217評(píng)論 0 0
  • 前有美景觀不得, 且居懸崖峭壁間黍翎。 個(gè)中滋味無人知面徽, 測(cè)遍名山與大川。
    文史雜壇閱讀 478評(píng)論 0 0
  • 年年歲歲花相似玩敏,歲歲年年人不同斗忌。 過去的一年,不論好事壞事旺聚,已經(jīng)成為往事织阳。如今站在2018年農(nóng)歷新年的門口,讓我們...
    since大白閱讀 155評(píng)論 0 0