python大佬養成計劃----flask_bootstrap裝飾網頁

flask_bootstrap

Bootstrap 是 Twitter 開發的一個開源框架,它提供的用戶界面組件可用於建立整潔且具備吸引力的網頁,並且這些網頁還能兼容全部現代 Web 瀏覽器.

Bootstrap 是客戶端框架,所以不會直接涉及服務器。服務器須要作的只是提供引用了 Bootstrap 層疊樣式表(CSS)和 JavaScript 文件的 HTML 響應, 而且 HTML、CSS 和 JavaScript 代碼中實例化所需組件。這些操做最理想的執行場所就是模版。

Flask-Bootstrap 能夠在程序中集成 Bootstrap

安裝:css

pip install flask-bootstrap

使用:html

from flask_bootstrap import Bootstrap
......
bootstrap = Bootstrap(app)

html文件的繼承

初始化 Flask-Bootstrap 以後,就能夠在程序中使用一個包含全部Bootstrap 文件的基模版。這個模版利用 Jinja2 的模版繼承機制,讓程序擴展一個具備基本頁面結構的基模版,其中就有用來引入 Bootstrap 的元素。python

bootstrap的base.html文檔:mysql

{% block doc -%}
<!DOCTYPE html>
<html{% block html_attribs %}{% endblock html_attribs %}>
{%- block html %}
  <head>
    {%- block head %}
    <title>{% block title %}{{title|default}}{% endblock title %}</title>

    {%- block metas %}
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    {%- endblock metas %}

    {%- block styles %}
    <!-- Bootstrap -->
    <link href="{{bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')}}" rel="stylesheet">
    {%- endblock styles %}
    {%- endblock head %}
  </head>
  <body{% block body_attribs %}{% endblock body_attribs %}>
    {% block body -%}
    {% block navbar %}
    {%- endblock navbar %}
    {% block content -%}
    {%- endblock content %}

    {% block scripts %}
    <script src="{{bootstrap_find_resource('jquery.js', cdn='jquery')}}"></script>
    <script src="{{bootstrap_find_resource('js/bootstrap.js', cdn='bootstrap')}}"></script>
    {%- endblock scripts %}
    {%- endblock body %}
  </body>
{%- endblock html %}
</html>
{% endblock doc -%}

繼承Bootstrap 文件的基模版,編寫適用於本身項目的基模板。jquery

{#本身編寫一個基類模板#}
{% extends 'bootstrap/base.html' %}

{% block styles %}
{{ super() }}
    <link rel="stylesheet" href="../static/css/main.css">
{% endblock %}
{% block navbar %}
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="index.html"></a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li><a href="#">首頁<span class="sr-only">(current)</span></a></li>
                <li><a href="#">新聞</a></li>
                <li><a href="#">國際</a></li>
                <li><a href="#">國內</a></li>
                <li><a href="/sysinfo/">系統信息</a></li>
                <li><a href="#">登錄用戶</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">

                {% if 'user' in session %}
                <li><a href="login.html"><span class="glyphicon glyphicon-user"></span>
                    &nbsp;&nbsp; {{ session.user }}</a></li>
                <li><a href="/logout/"><span class="glyphicon glyphicon-log-in"></span>
                    &nbsp;&nbsp; 註銷 </a></li>


                {% else %}

                <li><a href="/login/"><span class="glyphicon glyphicon-log-in"></span>
                    &nbsp;&nbsp;登錄</a></li>
                {% endif %}


                <li><a href="/register/"><span class="glyphicon glyphicon-log-out"></span>
                    &nbsp;&nbsp;註冊</a></li>
            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>
{% endblock %}

{% block content %}
{#定義屬於本身的block#}
    {% block newcontent %}


    {% endblock %}

    {% block footer %}
<div class="footer">


    宇宙大魔王--ZAJ


</div>
{% endblock %}
{% endblock %}

Jinja2 中的 extends 指令從 Flask-Bootstrap 中導入 bootstrap/base.html,從而實現模版繼承。Flask-Bootstrap 中的基模版提供了一個網頁框架,引入了 Bootstrap 中的全部 CSS 和 JavaScript 文件。sql

上面這個示例從新定義了3個塊,分別是對 bootstrap/base.html的styles、navbar和content的改寫。這些塊都是基模版提供的,可在衍生模版中從新定義。數據庫

若是程序須要向已經有內容的塊中添加新內容, 必須使用 Jinja2 提供的 super() 函數。例如,若是要在衍生模版中添加新的 CSS 文件,須要這麼定義:flask

{% block styles %}
{{ super() }}
    <link rel="stylesheet" href="../static/css/main.css">
{% endblock %}

使flask_bootstrap和flask_wtf編寫一個FLASK項目

要求:bootstrap

實現網頁主頁顯示、登錄頁面顯示、註冊頁面顯示、用戶退出(註銷)。而且只有數據庫中存在用戶能夠登錄網頁。主要經過表單來實現數據交互。目前,對於用戶註冊,不返回數據庫。

實現數組

模板文件有templates/base.html , templates/index.html , templates/login.html , templates/register.html 
Py文件有 zaj_run.py , zaj_ forms.py , zaj_modles.py , zaj_config.py

模板文件連接

連接:https://pan.baidu.com/s/1Uov-i8b2fZMr9fOe32tcgg 
提取碼:jrbs
# zaj_run.py
from flask import Flask,render_template,session,redirect,url_for
from flask_bootstrap import Bootstrap
from zaj_forms import LoginForm,RegisterFrom
from zaj_models import isPasswdOk
import  functools
app = Flask(__name__)

app.config['SECRET_KEY'] = 'SHEEN'
bootstrap = Bootstrap(app)

def is_login(f):
    """判斷用戶是否登錄的裝飾器"""
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        # 主函數代碼裏面, 若是登錄, session加入user, passwd兩個key值;
        # 主函數代碼裏面, 若是註銷, session刪除user, passwd兩個key值;
        # 若是沒有登錄成功, 則跳轉到登錄界面
        if 'user' not in session:
            return  redirect('/login/')
        # 若是用戶是登錄狀態, 則訪問哪一個路由, 就執行哪一個路由對應的視圖函數;
        return  f(*args, **kwargs)
    return  wrapper

@app.route('/')
def index():
    return render_template('index.html')
@app.route('/login/',methods=['GET','POST'])
def login():
    # session.pop('user',None)
    # session.pop('passwd',None)
    form  = LoginForm()
    print(form.data)    #{'user': 'root123', 'passwd': 'sheen123', 'submit': True,....}
    if form.validate_on_submit():
        user = form.data['user']
        passwd = form.data['passwd']
        if isPasswdOk(user,passwd):
            session['user'] = user
            session['passwd'] = passwd
            return redirect(url_for('index'))
        else:
            return render_template('login.html',form=form,message='密碼或用戶名錯誤')
    else:
        return render_template('login.html',form=form)
@app.route('/register/',methods=['GET','POST'])
def register():
    form = RegisterFrom()
    # 若是是post方法而且表單驗證經過的話, 返回True;
    if form.validate_on_submit():
        # 用戶提交的表單信息
        print(form.data)
        return 'ok'
    return  render_template('register.html', form=form)
@app.route('/logout/')
def logout():
    session.pop('user', None)
    session.pop('passwd', None)
    # 註銷即刪除用戶的session信息, 註銷成功, 跳轉到首頁;
    return  redirect(url_for('index'))
    # return  redirect('/')

if __name__ == '__main__':
    app.run( port = 8900)
# 報錯1:TypeError: __init__() takes from 1 to 2 positional arguments but 3 were given
# 解決:把輸入表單LoginForm,RegisterFrom中的Required去掉

# 問題2:每次從新運行程序,都會顯示root123用戶已登錄,即session裏面有數據
# 解決:添加判別session內容的函數is_login()。
# zaj_models.py,存放數據庫操做
import pymysql
from zaj_config import  DB


# 1. 建立鏈接
conn  = pymysql.connect(
        host=DB.HOST,
        user = DB.USER,
        passwd = DB.PASSWD,
        port = DB.PORT,
        db = DB.DBNAME,
        )

cur = conn.cursor()



def isUserExist(username):
    """判斷用戶名是否存在"""
    sqli = "select * from user where name='%s'" %(username)
    res = cur.execute(sqli)
    # res返回的是sql語句查詢結果的個數;
    #  若是爲0, 沒有查到。
    if res == 0:
        return  False
    else:
        return  True


def isPasswdOk(username, passwd):
    sqli = "select * from user where name='%s' and passwd='%s'" %(
        username, passwd)
    res = cur.execute(sqli)
    if res == 0 :
        return  False
    else:
        return  True


def addUser(username, passwd):
    """用戶註冊時, 添加信息到數據庫中"""
    sqli = "insert into user(name, passwd) values('%s', '%s')" %(
        username, passwd)
    try:
        res = cur.execute(sqli)
        conn.commit()
    except Exception as e:
        conn.rollback()
        return e
#
# cur.close()
# conn.close()
if __name__ == "__main__":
    addUser('root', 'root')
    print(isUserExist('root'))
    print(isPasswdOk('root', 'root'))
# zaj_forms.py,存放表單操做
from flask_wtf import FlaskForm
# 每一個Web表單都由一個繼承自FlaskForm的類表示
from wtforms import StringField,PasswordField,SubmitField
# StringField類表示的是屬性爲type="text"的<input>元素。
# SubmitField類表示的是是屬性爲type="submit"的<input>元素

#WTForms內建的驗證函數validators,並且是以數組形式,正對應了前面說的一個字段能夠有一個或者多個驗證函數
from wtforms.validators import Length, Required, EqualTo, Regexp,Email


class LoginForm(FlaskForm):
    user = StringField(
        label='用戶名',
        validators=[
            Length(5,13)
        ]
    )
    passwd = PasswordField(
        label='密碼',
        validators=[
            Length(6,12),
        ]
    )
    submit = SubmitField(
        label='登錄'
    )
class RegisterFrom(FlaskForm):
    user = StringField(
        label='用戶名/郵箱/手機號',
        validators=[
            Length(5,13)
        ]
    )
    passwd = PasswordField(
        label='密碼',
        validators=[
            Length(6,12),
        ]
    )
    repasswd = PasswordField(
        label='確認密碼',
        validators=[
            EqualTo('passwd',message='密碼不一致!')
        ]
    )
    phone = StringField(
        label='電話號碼',
        validators=[
            Regexp(r'1\d{10}', message='手機號碼格式錯誤')
        ]
    )
    email = StringField(
        label='郵箱',
        validators=[
            Email(message='郵箱格式錯誤!')
        ]
    )
    submit = SubmitField(
        label='註冊'
    )
# zaj_config.py , 存放數據庫類
class DB:
    HOST = 'localhost'
    USER= 'root'
    PASSWD = 'sheen'
    PORT = 3306
    DBNAME = 'zaj_form'

確保數據庫zaj_form中已有表user,user有元素name,passwd,添加用戶name= ‘python’ , passwd=’1234567’
主頁:
圖片描述
登錄以後,自動跳轉主頁,顯示session的緩存。
圖片描述
當註冊表單某一項不知足程序定義的規則時
圖片描述
當註冊成功時,返回'OK'
圖片描述

相關文章
相關標籤/搜索