flask 項目結構,完成一個注冊,登陸功能。


項目介紹

項目架子:

  

 

 

完成添加后台用戶功能

登錄的功能 基於flask_script ,因為說后台管理用戶,所以以命令的形式添加,不接受注冊。鞏固flask_script 在實際開發中的應用場景。

首先在models 中定義用戶表:

字段定義有:姓名,郵箱,密碼,簽名,用戶創建時間

 1 #encoding:utf-8
 2 from exts import db
 3 from datetime import datetime
 4 from werkzeug.security import generate_password_hash,check_password_hash
 5 
 6 class User(db.Model):
 7     __tablename__='user'
 8     id=db.Column(db.Integer,primary_key=True,autoincrement=True)
 9     name=db.Column(db.String(50),nullable=False)
10     email=db.Column(db.String(100),nullable=False,unique=True)
11     _passwd=db.Column(db.String(100),nullable=False)
12     # 簽名
13     autograph=db.Column(db.String(50))
14     join_time=db.Column(db.DateTime,default=datetime.now)
15 
16     def __init__(self,n,e,p,a):
17         self.name=n
18         self.email=e
19         self.passwd=p
20         self.autograph=a
21 
22     @property
23     def passwd(self):
24         return self._passwd
25 
26     @passwd.setter
27     def passwd(self,raw_pwd):        # 用戶的密碼利用 generate_password_hash函數 加密。 28         self._passwd=generate_password_hash(raw_pwd)
29 
30     def check_passwd(self,pwd):   # 用戶密碼檢查,判斷輸入的密碼是否正確 31         return check_password_hash(self.passwd,pwd)

 

定義了實體模型之后,我們需要把類隱射到數據庫中,首先我們看程序主文件,PGpureLove.py

 

from flask import Flask       
from apps.home import home_bp
from apps.admin import bp as admin_bp
from exts import db,mail
from flask_wtf import CSRFProtect
import config

def create_app():   # 定義工廠函數,創建app對象。
    app = Flask(__name__)        #Flaks方法 創建app對象
    app.config.from_object(config)   #綁定配置信息
    app.register_blueprint(home_bp)  #注冊藍圖 前台
    app.register_blueprint(admin_bp) #注冊藍圖 后台 
    db.init_app(app)          #讓app 應用程序使用這個數據庫設置
    mail.init_app(app)         #同上, 發送郵件時使用         
    CSRFProtect(app)
    return app

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

 

app對象創建好之后,看下manage.py 文件:

#encoding:utf-8
from flask_script import Manager            # 導入Manager 重要 必不可少。
from flask_migrate import Migrate,MigrateCommand   # 做數據遷移用。
from PGpureLove import create_app           #導入工廠函數 
from exts import db                    #導入sqlalchemy 的實例對象
from apps.admin import models as admin_models       #引入數據模型
AdminUser=admin_models.User                #實例化
app=create_app()                      #創建一個app
manager=Manager(app)                                #Manger綁定app
Migrate(app,db)                      #綁定 app 與db    


manager.add_command('db',MigrateCommand)    #MigrateCommand封裝了一套數據遷移的命令     

@manager.option('-n','--name',dest='name')
@manager.option('-p','--passwd',dest='passwd')
@manager.option('-e','--email',dest='email')
@manager.option('-a','--autograph',dest='autograph')
def create_Admin(name,passwd,email,autograph):
    u=AdminUser(name,email,passwd,autograph)
    db.session.add(u)
    db.session.commit()
    print("<用戶已經創建>")


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

 

在實際的開發環境中,經常會發生數據庫修改的行為。一般我們修改數據庫不會直接手動的去修改,而是去修改ORM對應的模型,然后再把模型映射到數據庫中。
flask-migrate是基於Alembic進行的一個封裝,並集成到Flask中,而所有的遷移操作其實都是Alembic做的,他能跟蹤模型的變化,並將變化映射到數據庫中。

 

1. 初始化一個環境:python manage.py db init 

2. 自動檢測模型,生成遷移腳本:python manage.py db migrate
3. 將遷移腳本映射到數據庫中:python manage.py db upgrade

檢查表,已經創建了:

 

4. 更多命令:python manage.py db --help

 

完成一三步之后,就可以使用 create_Admin 創建后台賬號了。

 查看數據庫

 

 

 完成前台的登錄功能

后台登錄功能:

  涉及flask 框架知識點: flask_script ,flask_migrate,藍圖,g對象,session,宏,flask_wtf

 

 

首先設計前台登錄頁面,頁面是網上找的:

 

首先定義一個宏。

 

登錄界面:

{% from 'comm/_maro.html' import static %}   // 導入宏
<!DOCTYPE html>

        <div class="animate form login_form">
          <section class="login_content">
            <form method="post">
                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
                <h1>登錄</h1>
                <div>
                  <input name="username" type="text" class="form-control" placeholder="郵箱號" required="">
                </div>
                <div>
                    <input name="password" type="password" class="form-control" placeholder="密碼" required="">
                    {% if message %}
                        <p style="text-align: center" class="text-danger">{{ message }}</p>
                    {% endif %}
                </div>

                <div class="checkbox3 checkbox-success checkbox-inline checkbox-check checkbox-round  checkbox-light">
                    <input name="remember" value="1" type="checkbox" id="checkbox-fa-light-1" checked="">
                    <label for="checkbox-fa-light-1">
                      記住密碼
                    </label>
                </div>
                <div>
                    <button class="btn btn-default submit" type="submit">登錄</button>
                    <a class="reset_pass" href="#">您的密碼丟失?</a>
                </div>

                <div class="clearfix"></div>

                <div class="separator">
                  <p class="change_link">第一次訪問網站?
                    <a href="http://demo.cssmoban.com/cssthemes4/cttp_1_gentelella/production/login.html#signup" class="to_register"> 注冊賬戶 </a>
                  </p>

                  <div class="clearfix">
                  </div>
                  <br>
                  <div>
                    <p>©2016 All Rights Reserved. Gentelella Alela! is a Bootstrap 3 template. Privacy and Terms</p>
                  </div>
                </div>
            </form>
          </section>
        </div>

 

這時候 需要創建 form.py 創建

 

from wtforms import Form

class BaseForm(Form):
    def get_error(self):
        return self.errors.items()[1][0]
from apps.forms import BaseForm
from wtforms import StringField,IntegerField,PasswordField
from wtforms.validators import Required,Email,EqualTo,Length,InputRequired
from flask import g
from utils import cacheLib

class LoginForm(BaseForm):
    username=StringField(validators=[Email(message='郵箱格式不正確'),InputRequired(message='請輸入郵箱')])
    password=StringField(validators=[InputRequired(message='請輸入密碼'),Length(6,50,message='密碼長度只能6-50')])
    remember=IntegerField()

 

完成之后 ,我們需要定義個一視圖來渲染login.html 頁面,進入views.py 中。

 
         
from flask import Blueprint,render_template,request,g,session,redirect,url_for
from .forms import LoginForm,RestPwdForm
from flask import views,render_template
from .models import User
from .decorators import login_requid

import config
from exts import db

bp=Blueprint('admin',__name__,url_prefix='/admin')

#
登錄功能 基於調度方法的視圖 class LoginView(views.MethodView): #需要繼承 MethodView方法 def get(self,message=None):   #get 請求登錄頁面 return render_template('comm/login.html',message=message) def post(self): #處理用戶提交的登錄信息 form=LoginForm(request.form) # 處理表單提交的數據 傳遞 request.form if form.validate():      # 如果驗證通過。 name=form.username.data #獲取用戶名 pwd=form.password.data #獲取密碼 remb=form.remember.data #獲取記住密碼 user=User.query.filter_by(email=name).first() #通過flask_sqlalchemy 查詢該用戶。 if user and user.check_passwd(pwd) :   #檢查輸入的密碼對不對,內部調用的check_password_hash方法,如果有這個用戶 並且密碼對的 session[config.CMS_USER_ID]=user.id # 首先把用戶di傳到seesion中 if remb: session.permanent=True return redirect(url_for('admin.index')) else: return self.get(message='密碼錯誤') else: return "驗證不通過" bp.add_url_rule('/login/',view_func=LoginView.as_view('login'))

登錄功能完成, 我們需要測試幾種場景:

表單驗證的信息

 

1 密碼輸入正確的時候,登錄正常

 

 

2 直接點登錄:

用戶名 密碼都會有提示,

但是這只說前端的驗證,后台我們同樣是要去處理這種異常情況。

 

3 用戶名或密碼輸入錯誤

建議不要提示太明顯,以前做測試的時候要求開發提示清晰,讓用戶知道自己說用戶名或者密碼輸錯了。

但這樣也不安全。活躍的用戶是不可能把賬號都忘掉的。

因為沒有使用ajax ,http是無狀態的,當輸入錯誤的郵箱或者密碼,我們想在表單中保留上次輸入的數據,這就需要在把數據回傳到render_templete 函數中。

 

 4 登錄成功,正常跳轉到首頁。

 

 

 

5 當用戶在登錄之后,我們需要驗證session。

這些頁面都說要登錄之后才能看到的。所以我們現在要來實現這個裝飾器。

from flask import session,redirect,url_for   
from functools import wraps               # 避免在使用的過程
from config import CMS_USER_ID
def login_requid(func):
    @wraps(func)
    def warp(*args,**kwargs):
        if CMS_USER_ID in session:
            return func(*args,**kwargs)
        else:
            return redirect(url_for('admin.login'))
    return warp

之后 只要在需要的地方引入即可。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM