flask3

hello.py文件是主頁(yè)面,在開(kāi)發(fā)時(shí)主頁(yè)面不要寫太多內(nèi)容,所以我們要優(yōu)化主頁(yè)面。
創(chuàng)建一個(gè)app包,


image.png
__init__.py文件必須要有,有了這個(gè)py文件
才能把a(bǔ)pp文件當(dāng)做一個(gè)庫(kù)來(lái)使用
然后再創(chuàng)建一個(gè)views.py文件用來(lái)
存放hello.py文件中的路徑文件
此時(shí)肯定會(huì)有很多的錯(cuò)誤,
@app.route('/')不能跨文件,我們
就需要在Terminal下載一個(gè)藍(lán)圖文件
pip install Blueprint

# 藍(lán)圖, 管理路由地址
# 第一步:生成藍(lán)圖對(duì)象
blue = Blueprint('first', __name__)

然后再hello.py(主頁(yè)面)
# app.views 此時(shí)它是一個(gè)庫(kù)了
導(dǎo)入
from app.views import blue
此時(shí)必須把from hello import app刪了, app已變成blue,
app不能跨文件,不刪就會(huì)循環(huán)導(dǎo)入會(huì)報(bào)錯(cuò)

第二步:管理藍(lán)圖
app.register_blueprint(blueprint=blue)  # 注冊(cè)一下

再回到views.py文件中
將所有的@app.route()改為
@blue.route()
再導(dǎo)入那些報(bào)紅的庫(kù)

views.py文件中
里面的redirect, url_for都是flask自帶的, 導(dǎo)出來(lái)就行了

from flask import render_template, make_response, \
    request, session, Blueprint, redirect, url_for

# from hello import app 沒(méi)用了 因?yàn)閍pp已改成blue, app不能跨py文
# 件, 不刪就會(huì)循環(huán)導(dǎo)入會(huì)報(bào)錯(cuò)
from utils.functions import is_login

# 藍(lán)圖, 管理路由地址
# 第一步: 生成藍(lán)圖對(duì)象
blue = Blueprint('first', __name__)


@blue.route('/')
def hello():
    return 'hello world'  # 這就是后端給前端的響應(yīng)的內(nèi)容


@blue.route('/make_res/')
def make_res():
    # make_response('響應(yīng)內(nèi)容', 響應(yīng)狀態(tài)碼)創(chuàng)建響應(yīng)對(duì)象 響應(yīng)狀態(tài)碼默認(rèn)為200
    # return make_response('hello flask day02', 200)
    # return make_response('<h2>今天天氣不好</h2>')
    index = render_template('first.index')
    return make_response(index, 200)


@blue.route('/register/', methods=['GET', 'POST'])
def register():
    print(request.method)
    if request.method == 'GET':
        return render_template('register.html')
    if request.method == 'POST':
        # 模擬注冊(cè)功能
        # 1.獲取頁(yè)面中傳遞的參數(shù)
        username = request.form.get('username')
        password = request.form.get('password')
        password2 = request.form.get('password2')
        # 模擬注冊(cè)
        if username == 'coco' and password == password2 \
                and password == '123456':
            # 返回登錄頁(yè)面
            return redirect(url_for('first.login'))  # 同時(shí)跳轉(zhuǎn)地址和頁(yè)面
            # return render_template('login.html') # 跳轉(zhuǎn)頁(yè)面,但不會(huì)修改地址
        else:
            return render_template('register.html')


@blue.route('/login/', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    if request.method == 'POST':
        # 1.獲取參數(shù)
        print(123)
        username = request.form.get('username')
        password = request.form.get('password')
        # 2.模擬登錄
        if username == 'coco' and password == '123456':
            # 向cookie中設(shè)置參數(shù) (鑰匙)
            print('899')
            res = make_response(redirect(url_for('first.index')))
            # 設(shè)置cookie
            res.set_cookie('token', '12345678', max_age=3000)
            return res
        else:
            return render_template('login.html')


@blue.route('/logout/')
def my_logout():
    # 注銷
    res = make_response(render_template('login.html'))
    res.delete_cookie('token')    # 刪除key值
    return res


@blue.route('/index/')
def index():
    # 登錄過(guò)后能看到index.html頁(yè)面, 沒(méi)有登錄跳轉(zhuǎn)到登錄頁(yè)面
    token = request.cookies.get('token')
    if token == '12345678':
        # 判斷登錄成功了
        return render_template('index.html')
    else:
        # 判斷登錄失敗了
        return render_template('login.html')


@blue.route('/session_login/', methods=['GET', 'POST'])
def session_login():
    if request.method == 'GET':
        return render_template('session_login.html')

    if request.method == 'POST':
        # 解析參數(shù)
        username = request.form.get('username')
        password = request.form.get('password')
        if username == 'coco' and password == '123456':
            # 向session會(huì)話中設(shè)置鍵值對(duì), 1代表True
            session['login_status'] = 1
            # session['name'] = 'coco'
            # session['pwd'] = '123456'
            return redirect(url_for('first.index'))
        else:
            return render_template('session_login.html')


@blue.route('/session_index/')
@is_login
def session_index():
    # if 'login_status' in session:

        return redirect(url_for('first.index'))
    # else:
    #    return render_template('session_login.html')


# 不用上面判斷, 一步完成
@blue.route('/xindex/')
@is_login
def xindex():
    # 登錄過(guò)后能夠訪問(wèn)index.html頁(yè)面
    # 沒(méi)有登錄不讓訪問(wèn),跳轉(zhuǎn)到session.html頁(yè)面
    return redirect(url_for('first.index'))


@blue.route('/session_logout/')
def session_my_logout():
    # 注銷
    del session['login_status']
    # return render_template('session_login.html')  # 重新渲染下頁(yè)面
    return redirect(url_for('first.session_login'))  # 和上面一樣


# 跳轉(zhuǎn)到一個(gè)函數(shù)
@blue.route('/redirect_func/')
def redirect_func():
    # 跳轉(zhuǎn)到登錄頁(yè)面
    # return render_template('login.html')
    # return redirect('/login/')  # 跳轉(zhuǎn)到這個(gè)地址上面, 類似昨天的action
    # url_for('藍(lán)圖第一個(gè)參數(shù).跳轉(zhuǎn)的函數(shù)名') 就可以不用寫render_template()了
    # return redirect(url_for('first.login'))  # 藍(lán)圖第一個(gè)參數(shù).函數(shù)名
    # 無(wú)參跳轉(zhuǎn)
    # return redirect('/s_id/1/')
    return redirect(url_for('first.s_id', id=1))  # 和上一步一樣
    # 的   這就是有參跳轉(zhuǎn)


@blue.route('/s_id/<int:id>/')
def s_id(id):
    return 's_id: %s' % id


# 模板內(nèi)容
@blue.route('/student/')
def stu():
    stus_score = [90, 89, 100, 99, 87, 67]
    content2_h2 = '<h1>睡覺(jué)</h1>'
    return render_template('stu.html', scores=stus_score, content2_h2=content2_h2)

上面文件中的is_login它是調(diào)用函數(shù)(為了簡(jiǎn)便,只在該頁(yè)面需要一步操作,)
創(chuàng)建一個(gè)utils包,里面有init.py和functions.py文件
functions.py文件里是一個(gè)裝飾器
functions.py文件中

from functools import wraps

from flask import session, render_template


# 裝飾器
# 裝飾器的三個(gè)條件:
# 1.外層函數(shù)嵌套內(nèi)層函數(shù)
# 2.外層函數(shù)返回內(nèi)層函數(shù)
# 3.內(nèi)層函數(shù)調(diào)用外層函數(shù)的參數(shù)
# 下面最簡(jiǎn)單的裝飾器結(jié)構(gòu):
def is_login(func):
    @wraps(func)  # 這步是讓函數(shù)調(diào)用自己的本身(session_index),
而不是is_login
    def check():
 # 獲取session是否登錄那個(gè)值,假如沒(méi)登錄就異常捕獲了,害怕報(bào)錯(cuò)
        try:
            session['login_status'] 
            # 登錄過(guò)后能夠訪問(wèn)index.html頁(yè)面
            return func()
        except:
            # 沒(méi)有登錄不讓訪問(wèn),跳轉(zhuǎn)到session.html頁(yè)面
            return render_template('session_login.html')
    return check


if __name__ == '__main__':
    pass

優(yōu)化完之后在hello.py文件中是這樣的

import redis    # 這行是第三方庫(kù), 下面也是
from flask import Flask
from flask_script import Manager

from flask_session import Session

# from utils.functions import is_login  # 自己寫的包(可以刪掉了)
from app.views import blue

app = Flask(__name__)  # 生成app對(duì)象

# 第二步: 管理藍(lán)圖
app.register_blueprint(blueprint=blue)  # 注冊(cè)一下

# 設(shè)置secret_key加密, 加密復(fù)雜程度和設(shè)置有關(guān),不能告訴別人的
# 此時(shí)存在cookie中的
app.secret_key = '1234567890'
#  沒(méi)有登錄不讓訪問(wèn),跳轉(zhuǎn)到session.html頁(yè)面ession.html頁(yè)面
# 配置session的信息
# from flask_session import Session
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.Redis(host='127.0.0.1', port=6379)
Session(app)  # 會(huì)話

manage = Manager(app)

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

將導(dǎo)入的庫(kù)變灰色的都刪掉, 同時(shí)要導(dǎo)入

from app.views import blue  
# 因?yàn)橛昧薬pp.register_blueprint(blueprint=blue)這句

二 優(yōu)化html文件

jinja2
通過(guò)父模板來(lái)優(yōu)化, 可以讓多個(gè)html文件同時(shí)使用一個(gè)父模板,這樣就免得寫很多相同的頁(yè)面和樣式。

flask使用操作指南之模板
1. jinja2
Flask中使用jinja2模板引擎
jinja2是由Flask作者開(kāi)發(fā),模仿Django的模板引擎
優(yōu)點(diǎn):
速度快,被廣泛使用

HTML設(shè)計(jì)和后端python分離

非常靈活,快速和安全

提供了控制,繼承等高級(jí)功能

2. 模板語(yǔ)法
2.1 模板語(yǔ)法主要分為兩種:變量和標(biāo)簽
模板中的變量:{{ var }}
視圖傳遞給模板的數(shù)據(jù)

前面定義出來(lái)的數(shù)據(jù)

變量不存在,默認(rèn)忽略

模板中的標(biāo)簽:{% tag %}
控制邏輯

使用外部表達(dá)式

創(chuàng)建變量

宏定義

2.2 結(jié)構(gòu)標(biāo)簽:
block
{% block xxx %}

{% endblock %}

塊操作
    父模板挖坑,子模板填坑

extends
{% extends ‘xxx.html’ %}

繼承以后保留塊中的內(nèi)容
{{ super() }}

挖坑繼承體現(xiàn)的化整為零的操作

macro

{% macro hello(name) %}

    {{ name }}

{% endmacro %}

宏定義,可以在模板中定義函數(shù),在其他地方調(diào)用

宏定義可導(dǎo)入

{% from 'xxx' import xxx %}

例子1:

在index.html中定義macro標(biāo)簽,定義一個(gè)方法,然后去調(diào)用方法,結(jié)果是展示商品的id和商品名稱

{% macro show_goods(id, name) %}
    商品id:{{ id }}
    商品名稱:{{ name }}
{% endmacro %}

{{ show_goods('1', '娃哈哈') }}
<br>
{{ show_goods('2', '雪碧') }}

例子2:

在index.html頁(yè)面中定義一個(gè)say()方法,然后解析該方法:

{% macro say() %}

    <h3>今天天氣氣溫回升</h3>
    <h3>適合去游泳</h3>
    <h3>適合去郊游</h3>

{% endmacro %}

{{ say() }}

例子3:

定義一個(gè)function.html中定義一個(gè)方法:

{% macro create_user(name) %}
    創(chuàng)建了一個(gè)用戶:{{ name }}
{% endmacro %}

在index.html中引入function.html中定義的方法

{% from 'functions.html' import create_user %}

{{ create_user('小花') }}

2.3 循環(huán)

{% for item in cols %}

    aa

{% else %}

    bb

{% endfor %}

也可以獲取循環(huán)信息loop

loop.first

loop.last

loop.index

loop.revindex

2.4 過(guò)濾器

語(yǔ)法:

{{ 變量|過(guò)濾器|過(guò)濾器... }}

capitalize 單詞首字母大寫
lower 單詞變?yōu)樾?upper 單詞變?yōu)榇髮?title
trim 去掉字符串的前后的空格
reverse 單詞反轉(zhuǎn)
format
striptags 渲染之前,將值中標(biāo)簽去掉
safe 講樣式渲染到頁(yè)面中
default
last 最后一個(gè)字母
first
length
sum
sort

例子:
<ul>
    <li>{{ content_h2 }}</li>
    <li>{{ content_h2|safe }}</li>
    <li>{{ content_h2|striptags }}</li>

    <li>{{ content_h3 }}</li>
    <li>{{ content_h3|length }}</li>
    <li>{{ content_h3|trim|safe }}</li>
    <li>{{ content_h3|trim|length }}</li>
</ul>

3. 定義模板

3.1 定義基礎(chǔ)模板base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {% block title %}
        {% endblock %}
    </title>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

    {% block extCSS %}
    {% endblock %}
</head>
<body>

{% block header %}
{% endblock %}

{% block content%}
{% endblock %}

{% block footer%}
{% endblock %}

{% block extJS %}
{% endblock %}

</body>
</html>

3.2 定義基礎(chǔ)模板base_main.html

{% extends 'base.html' %}

{% block extCSS %}
    <link rel="stylesheet" href="{{ 
url_for('static', filename='css/mai
n.css') }}">
{% endblock %}

首先我們?cè)趖emplates創(chuàng)建base.html文件, base_main.html文件
base.html文件中

<!--此時(shí)這個(gè)頁(yè)面是個(gè)框架, 父模板-->
<!--父模板挖坑, 子模板沒(méi)必要都要填坑-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        <!--jinja2 title是命名 俗稱挖坑-->
        {% block title %}
        {% endblock %}
    </title>
    {% block css %}
    {% endblock %}

    {% block js %}
    {% endblock %}
</head>
<body>
      <!--content是命名-->
      {% block content %}
       {% endblock %}
</body>
</html>

base_main.html文件中

{% extends 'base.html' %}
<!--繼承某個(gè)模板-->
<!--讓每個(gè)頁(yè)面都引用下面這個(gè)js-->

{% block js %}

   <!--初始化引入juquery.js-->
   <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
{% endblock %}

stu.html頁(yè)面

<!--繼承 網(wǎng)頁(yè)上顯示的是下面的頁(yè)面的而不是stu了-->
<!--先繼承 再填坑, 子模板沒(méi)必要都填坑,沒(méi)用就不填-->
<!--坑的名字必須唯一-->
<!--{{ a }} 就是在html上打印a 里面a是變量-->
{# {{ 注釋 }} #}
{% extends 'base_main.html' %}



{% block title %}
  學(xué)生列表頁(yè)面
{% endblock %}

{% block css %}
        <!--第一種寫法-->
       <!--<link rel="stylesheet" href="/static/css/style.css">-->
       <!--第二種寫法-->
       <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
{% endblock %}

{% block js %}
       {{ super() }}
       <script src="23231dewdde.js"></script>
       {# {{ 此時(shí)不會(huì)顯示base_main里面的js,因?yàn)橹伙@示這個(gè), 當(dāng)加了{(lán){ super() }}之后兩個(gè)都會(huì)顯示 }} #}
{% endblock %}

{% block content %}
     <!--過(guò)濾器 | - 管道符  safe-加載樣式 striptags取消標(biāo)簽-->
     <p>{{ content2_h2 | safe }}</p>
     <p>{{ 'Python' | length }}</p>
     <p>{{ 'Python' | upper }}</p>
     <p>{{ 'Python' | lower }}</p>
      <p>{{ 'Python' | upper | length }}</p>
      <p>{{ 'Python' | reverse }}</p>
      <p>{{ content2_h2 | striptags }}</p>

     <!--解析變量使用 {{ 變量名 }}-->
     <p> {{ scores }} </p>

     <!--解析標(biāo)簽, extends, block, for-->
     <ul>
         {% for a in scores %}
             <!--顯示列表的數(shù)字-從0開(kāi)始(類似于下標(biāo))  revindex倒著排序-->
             {{ loop.index0 }}
             <!--判斷是否為第一個(gè)(是就為True,不是則為False)和最后一個(gè)-->
             {{ loop.first }}
             {{ loop.last }}
             <li {% if loop.first == 1 %} style="color:yellow;" {% endif %}>
                 {{ a }}
             </li>
         {% else %}
             <li>沒(méi)有學(xué)生成績(jī)數(shù)據(jù)</li>
         {% endfor %}

     </ul>
<table>
     <thead>
         <th>姓名</th>
         <th>年齡</th>
     </thead>
     <tbody>
            <tr>
             <td>張三</td>
             <td>28</td>
             </tr>
            <tr>
                <td>李四</td>
                <td>29</td>
            </tr>
     </tbody>
</table>
{% endblock %}

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

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

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 3,214評(píng)論 0 3
  • 1. 對(duì)學(xué)生數(shù)據(jù)進(jìn)行CRUD操作 語(yǔ)法: 獲取查詢集: 數(shù)據(jù)操作: 1.1 想學(xué)生表中添加數(shù)據(jù) 提交事務(wù),使用co...
    曉曉的忍兒閱讀 554評(píng)論 0 0
  • (一)、啟動(dòng)服務(wù)器 (二)、創(chuàng)建數(shù)據(jù)庫(kù)表 或 更改數(shù)據(jù)庫(kù)表或字段 Django 1.7.1及以上 用以下命令 1....
    夏天夏星閱讀 5,968評(píng)論 0 17
  • 隨著天氣暖和,減肥的節(jié)奏就瘋狂起來(lái)~ 看到這張圖,是不是有了減肥的斗志?! 我們感官最容易被美好的事物所沖擊,我們...
    甜甜姐Sweety閱讀 480評(píng)論 0 0
  • 今晚在休斯頓豐田中心現(xiàn)場(chǎng)看了人生中的首場(chǎng)NBA比賽,火箭VS老鷹。 6點(diǎn)左右的時(shí)候,我們還在逛沃爾瑪,最后決定去看...
    一條豬閱讀 611評(píng)論 0 0

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