期末做品檢查

 

1、我的學期總結

 

    本人在一學期時間內學習並實現基於Python的Flask框架web建設項目,python是一種面向對象的解釋型計算機程序設計語言,由荷蘭人Guido van Rossum於1989年發明,Python是純粹的自由軟件, 源代碼解釋器CPython遵循 GPL(GNU General Public License)協議。Python語法簡潔清晰,特點之一是強制用空白符(white space)做爲語句縮進。下面簡單分享一下我我的學習python語言後的一些心得和經驗。css

    一開始接觸python咱們學的是簡單的輸出輸入交互和一些數字的計算,有點相似JAVA,但在語法上仍是有些區別,python語言優勢在於它的簡潔靈活,因此不少時候它都用到符號代替,接着咱們import turtle庫,並繪製出多種多樣的圖形,學習了字符串基本操做,凱撒密碼,自制九九乘法表,中英文詞頻統計等等,雖然語句都挺簡單,但這激發了咱們對學習python的興趣,並提高了咱們對編程語言的思惟能力,有助於下半學期咱們構建Flask框架製做網頁的學習。html

    在學習Python+Flask+MysqL的web建設時,咱們安裝了mySQL,pycharm和一些python的第三方庫,首先,老師教了咱們網頁前端的製做,應用超文本標記語言HTML,初學html,第一次知道五花八門的網頁原來是由許許多多的標籤對組成的,雖然感受學起來並不難,可是卻很繁瑣,例如每個網頁的標籤對有不少個,每個都有它特定的一些功能,包含了標籤對裏的衆多參數,要想實現這些標籤對的功能就必須遵循它的書寫規則,一旦有某個字母拼寫錯誤就會報錯,在html裏會用顏色的不一樣來報錯,這種狀況還較好處理,但在JS代碼中是不會提示你哪裏出錯,因此在編寫過程當中要多加細心謹慎。代碼簡單易學是好事,但要作出漂亮好看的前端也是須要有必定的基礎和積累的。雖然繁瑣但卻又頗有趣,剛開始接觸html+css+js的時候會想各類辦法去把網頁作好看,嘗試了各類各樣的樣式和標籤對,或者從網頁上cope別人作好的樣式代碼去修改,碰到不會的代碼就問百度解答或同窗探討,在這過程當中又學會了許多課堂上沒有教過的知識,最終作出的頁面雖然不盡人意,但對初學html的本菜鳥來講也算勉勉強強及格了。前端

    在頁面前端咱們作了導骯頁面、登錄註冊頁面、發佈頁面以及各自的css和js,在作這些頁面過程當中常常碰到一些問題,例如頁面的排版分佈,div中文本的居中問題,解決的辦法很簡單,只須要設置好對應div的class,但一開始都會用一些蠢辦法,用空格代替或者用&nbsp去填充,雖然說不是最佳的解決方法,但也達到了一樣的效果,在後端建設過程當中咱們引入了flask庫中的Flask, render_template,用於建立一個Flask對象以及頁面的跳轉,引入flask_sqlalchemy庫進行數據庫的關聯映射等,在引入這些庫時沒有太大問題,基本上屬於複製粘貼或照代碼打,但要注意python若是沒有這些庫的話要去命令行先安裝,在後端設計過程咱們學了對數據的增刪改查等操做,利用對數據庫的查詢添加功能實現了頁面的登錄、註冊以及發佈功能,這些功能的實現根據前端頁面的name屬性名,後臺請求接收同名name的值,再將接收的值作一系列增刪查改操做。在對這些name屬性命名時要注意先後端對應且同一頁面不能出現相同名,不然會出現數據傳遞出錯,在作頁面繼承中我就由於忽視了導航頁和登錄註冊頁的同名name屬性,致使了作好的js代碼因接收了錯的數據而失效,在context_processor上下文處理器中也要注意這個問題,由於上下文處理器帶的模型數據能夠在全部頁面模板中使用,所以要防止跟各自頁面的請求模型數據同名,一旦重名,數據就會帶錯,頁面上雖然不會報錯,但卻會顯示錯誤的數據給用戶,因此在編程過程當中要時刻注意代碼的簡潔清晰和條理性,儘可能用更少更優化的代碼實現功能。python

    在作發佈詳情中咱們在頁面跳轉請求時帶上須要用到的‘id’,利用該‘id’去後臺查詢數據,在作用戶詳情時咱們用三個頁面跳轉同一個請求,不一樣的是在請求中用if語句判斷,判斷各自實現的功能並跳轉不一樣頁面,一樣在作這些功能時要注意代碼的簡潔,能分開表示的代碼儘可能不要擠在一塊兒,注意代碼的規範和格式。不一樣功能的實現有不一樣的方法,同一功能的實現也可能有多種方法,多思考用不一樣的方法實現會幫助咱們開拓編程思惟,不必定要照着老師的作法墨守成規,一樣,當有不一樣的方法實現功能時咱們要儘可能嘗試,並進行比較選出比較優質的代碼進行替換。在編寫代碼時咱們也要養成一個好的習慣,多用「Ctrl+Alt+L」進行格式化以便咱們清晰的去觀察和修改,明確目標和功能,理解清晰原理和思路再着手編寫,在寫好某個功能的代碼後先按原理檢查是否出錯, 再運行頁面驗證功能,出錯時不要驚慌,先用F12打開頁面控制檯查看數據發送、接收狀況和紅色報錯項目,或者到pycharm後臺裏找相應的報錯字眼、提示等等。養成良好的習慣還在於多用「Ctrl+/」打註釋,把我的的理解和思路整理成簡單的註釋,不只方便本身複習和修改還有利於使用者及他人查看學習。mysql

    總之,編程是一門藝術活,像作建築通常,字母是它的鋼筋水泥和磚塊,只有實打實的基礎,地基牢固,才能成就崛起的名勝古蹟。其實編程也像作數學題,一道數學題目可能有多種解法,但咱們沒必要要像解數學題那樣講得很詳細,只要一目瞭然並能清晰簡潔的表達和實現功能便可,只有多去練習多去運用它,少用複製粘貼、投機取巧,咱們才能在編程道路上越走越遠。web

2017-12-2817:24:19sql

 

2、Python+Flask+MysqL的web建設技術過程總結

本人在一學期時間實現了Python+Flask+MysqL的web建設,頁面具備簡單的登陸註冊發佈文章搜索文章等功能。數據庫

在這裏總結分享了我最近一段時間的學習成果:使用Flask框架搭建一個web service,並在其中加上一些簡單的css,js,html等。因爲本人是新手,若有錯漏請見諒並歡迎你們批評指出。O(∩_∩)O編程

 

 一、使用工具

主要工具備:pycharm64.exe + Python 3.6 64-bit + MySQL + Navicat for MySQL(輔助工具)flask

   

主要內容是實現此頁面全部的static文件、templates文件與py文件:

二、完成基本的頁面設計

①.導航條(父模板)

②.登錄界面

③.註冊界面

 

④.發佈問答界面

 

三、涉及到的第三方庫和Flask & 概覽

主py文件:

manage.py(用於數據庫遷移):

Flask

複製代碼
from flask import Flask app = Flask(__name__) # 建立Flask對象 @app.route('/lin/') # 跳轉簡單測試。 def lin(): return 'lin' if __name__ == '__main__': app.run(debug=True)
複製代碼

四、加載靜態文件,父模板與其餘界面的繼承

①.url_for運用

from flask import url_for

跳轉後端請求:

<a class="navbar-brand" href="{{ url_for('daohang') }}">首頁</a> <a href="{{ url_for('yonghu',username_id=userid,tag=1) }}">我的信息</a></li>

加載靜態文件(可用於加載css, js, image文件):

<link rel="stylesheet" href="{{ url_for('static',filename='css/daohang.css') }}"> <script src="{{ url_for('static',filename='js/daohang.js') }}"></script>

②.繼承和擴展

目的在於把一些公共的代碼放在父模板中,避免每一個模板寫一樣的內容。

子模板繼承父模板。

父模板提早定義好子模板能夠實現一些本身需求的位置及名稱,子模板在相同名繼承塊中寫代碼實現本身需求。

注意{% block %}{% endblock %}裏的命名。

{% extends 'daohang.html' %} {% block denglutitle %}{% endblock %} {% block dengluhead %}{% endblock %} {% block daohangbody %}{% endblock %}

五、數據庫鏈接池

運用工具:MySQL + Navicat for MySQL(輔助工具)

①.安裝與配置:

下載安裝MySQL數據庫

下載安裝Navicat for MySQL

下載安裝第三方庫MySQL-python 中間件(pip install flask-sqlalchemy (Python的ORM框架SQLAlchemy))

②.運用但是化工具Navicat for MySQL建立數據庫

③.數據庫配置信息config.py

複製代碼
import os DEBUG = True SECRET_KEY = os.urandom(24) DIALECT = 'mysql' DRIVER = 'mysqldb' USERNAME = 'root' PASSWORD = 'ROOT' HOST = '127.0.0.1' PORT = '3306' DATABASE = 'mis_db' # 配置和數據庫的鏈接信息 SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:@localhost/mis_db?charset=utf8' SQLALCHEMY_TRACK_MODIFICATIONS = False
複製代碼

④.創建mysql和app的鏈接

複製代碼
from flask import Flask from flask_sqlalchemy import SQLAlchemy import config app = Flask(__name__) # 建立Flask對象 app.config.from_object(config) # 關聯config.py文件進來 db = SQLAlchemy(app) # 創建和數據庫的關係映射 class Comment(db.Model): __tablename__ = 'comment' id = db.Column(db.Integer, primary_key=True, autoincrement=True) author_id = db.Column(db.Integer, db.ForeignKey('user.id')) fabu_id = db.Column(db.Integer, db.ForeignKey('fabu.id')) creat_time = db.Column(db.DateTime, default=datetime.now) detail = db.Column(db.Text, nullable=False) fabu = db.relationship('Fabu', backref=db.backref('comments', order_by=creat_time.desc)) # order_by=creat_time.desc按時間降序 author = db.relationship('User', backref=db.backref('comments')) db.create_all() # 測試是否鏈接成功  @app.route('/lin/') # 跳轉測試。 def lin(): return 'lin' if __name__ == '__main__': app.run(debug=True)
複製代碼

⑤.建立用戶模型

class User(db.Model):  # 建立類User ... class Fabu(db.Model): ... class Comment(db.Model): ...

六、經過用戶模型,對數據庫進行增刪改查

複製代碼
# 插入功能 user = User(username='15',password='12') db.session.add(user) db.session.commit() # 查詢功能 user=User.query.filter(User.username=="15").first() print(user.username,user.password) # 修改功能 user=User.query.filter(User.username=="15").first() user.password='888' db.session.commit() # 刪除功能 user=User.query.filter(User.username=="15").first() db.session.delete(user) db.session.commit()
複製代碼

七、完成註冊功能

 ①.html文件:

<form>中設置 action和method="post"

<input> 中設置 name

<button>中onclick="return fnLogin()"

②.js文件:

運用一系列if函數判斷

onclick函數return True時才提交表單,return False時不提交表單。

③.主py文件中:

from flask import  request, redirect, url_for

複製代碼
# 跳轉註冊。 @app.route('/zhuce/', methods=['GET', 'POST']) # methods定義它有兩種請求方式,由於它在表單的請求是post,相似咱們在idea中的sava請求模式 def zhuce(): if request.method == 'GET': return render_template('zhuce.html') else: username = request.form.get('user') # post請求模式,安排對象接收數據 password = request.form.get('pass') nickname = request.form.get('nickname') user = User.query.filter(User.username == username).first() # 做查詢,並判斷 if user: return u'該用戶已存在' else: user = User(username=username, password=password, nickname=nickname) # 將對象接收的數據賦到User類中,即存到數據庫 db.session.add(user) # 執行操做  db.session.commit() return redirect(url_for('denglu')) # redirect重定向
複製代碼

八、完成登錄功能

相似註冊功能

複製代碼
# 跳轉登錄。 @app.route('/denglu/', methods=['GET', 'POST']) # methods定義它有兩種請求方式 def denglu(): if request.method == 'GET': return render_template('denglu.html') else: username = request.form.get('user') # post請求模式,安排對象接收數據 password = request.form.get('pass') user = User.query.filter(User.username == username).first() # 做查詢,並判斷 if user: # 判斷用戶名 if user.check_password(password): # 判斷密碼 session['user'] = username # 利用session添加傳回來的值username session.permanent = True # 設置session過時的時間 return redirect(url_for('daohang')) else: return u'用戶密碼錯誤' else: return u'用戶不存在,請先註冊'
複製代碼

(補充)session功能:

from flask import session

①.操做字典同樣操做`session`:

session['user'] = username # 利用session添加傳回來的值username session.permanent = True # 設置session過時的時間  session.get('user'):

②.放在上下文處理器中能夠在任何模板頁面中調用:

複製代碼
@app.context_processor  # 上下文處理器,定義變量而後在全部模板中均可以調用,相似idea中的model def mycontext(): user = session.get('user') if user: return {'sessionusername': user} # 包裝到username,在全部html模板中可調用 else: return {} # 返回空字典,由於返回結果必須是dict
複製代碼

九、登陸後更新導航

①.用上下文處理器app_context_processor定義函數,把登錄時定義的session get進來

複製代碼
@app.context_processor  # 上下文處理器,定義變量而後在全部模板中均可以調用,相似idea中的model def mycontext(): user = session.get('user') if user: return {'sessionusername': user} # 包裝到username,在全部html模板中可調用 else: return {} # 返回空字典,由於返回結果必須是dict
複製代碼

②.在父模板中更新導航,利用if函數判斷,插入登陸狀態判斷代碼

複製代碼
                {% if sessionusername %}
                    <li><a href="#" onclick="">{{ sessionusername }}</a></li> <li><a href="{{ url_for('logout') }}" onclick=""><span class="glyphicon glyphicon-log-out"></span> 註銷</a></li> {% else %} <li><a href="{{ url_for('denglu') }}" onclick=""><span class="glyphicon glyphicon-log-in"></span> 登錄</a> </li> <li><a href="{{ url_for('zhuce') }}" onclick=""><span class="glyphicon glyphicon-user"></span> 註冊</a></li> {% endif %}
複製代碼

    注意用{% ... %}表示指令,區分後臺和前端的if判斷。

    {{ }}表示變量

③.完成註銷功能

清楚session並跳轉

# 跳轉註銷。 @app.route('/logout') def logout(): session.clear() # 註銷時刪除全部session return redirect(url_for('daohang'))

十、完成發佈功能(和登錄註冊相似)

①.編寫請求登陸的裝飾器:

複製代碼
# 跳轉某頁面以前先進行登陸。定義decorator能夠加強函數功能,裝飾器自己是函數,入參是函數,返回值也是函數 def loginFirst(fabu): @wraps(fabu) # 加上wraps,它能夠保留原有函數的__name__,docstring def wrapper(*args, **kwargs): # 定義wrapper函數將其返回,用*args, **kwargs把原函數的參數進行傳遞 if session.get('user'): # 只有通過登錄,session才能記住並get到值 return fabu(*args, **kwargs) else: return redirect(url_for('denglu')) return wrapper
複製代碼

②.應用裝飾器:

@loginFirst  # 將decorator定義的加強函數放在待加強函數定義的上面
@app.route('/fabu/', methods=['GET', 'POST']) # methods定義它有兩種請求方式 @loginFirst # 將decorator定義的加強函數放在待加強函數定義的上面 def fabu():

③.創建發佈內容的對象關係映射

複製代碼
class Fabu(db.Model): __tablename__ = 'fabu' id = db.Column(db.Integer, primary_key=True, autoincrement=True) title = db.Column(db.String(100), nullable=False) detail = db.Column(db.Text, nullable=False) creat_time = db.Column(db.DateTime, default=datetime.now) # 提交時間會本身賦值 author_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 數據類型是db.Integer,db.ForeignKey參數指定外鍵是哪一個表中哪一個id author = db.relationship('User', backref=db.backref('fabu')) # 創建關聯,其author屬性將返回與問答相關聯的用戶實例,至關於數據庫中的錶鏈接 # 第一個參數代表這個關係的另外一端是哪一個類,第二個參數backref,將向User類中添加一個fabu屬性,從而定義反向關係,這一屬性可訪問Fabu類,獲取的是模型對象
複製代碼

④.完成發佈函數,保存數據庫,重定向到首頁

複製代碼
# 跳轉發布。 @app.route('/fabu/', methods=['GET', 'POST']) # methods定義它有兩種請求方式 @loginFirst # 將decorator定義的加強函數放在待加強函數定義的上面 def fabu(): if request.method == 'GET': return render_template('fabu.html') else: title = request.form.get('title') # post請求模式,安排對象接收數據 detail = request.form.get('detail') author_id = User.query.filter( User.username == session.get('user')).first().id # 將session get到的user進行查詢並取出id放到外鍵author_id中 fabu = Fabu(title=title, detail=detail, author_id=author_id) # 將對象接收的數據賦到Fabu類中,即存到數據庫 db.session.add(fabu) # 執行操做 db.session.commit() # 提交到數據庫 return redirect(url_for('daohang')) # redirect重定向
複製代碼

十一、在首頁顯示問答列表(可自行選擇顯示內容,本文以顯示問答內容爲例)

①.在首頁添加顯示問答的無序列表

複製代碼
            <div class="col-md-6 column s1"> <h3 class="text-center">發佈</h3> <ul class="list-unstyled"> {% for foo in fabus %} <li class="list-group-item-success"> <a href="{{ url_for('yonghu',username_id=foo.author_id,tag=1) }}"><span class="glyphicon glyphicon-fire"></span>{{ foo.author.username }}</a> <h4 class="text-center"><a href="{{ url_for('fabuview',fabu_id=foo.id) }}">{{ foo.title }}</a></h4> <span class="badge pull-right">{{ foo.creat_time }}</span> <br> <p>{{ foo.detail }}</p> </li> {% endfor %} </ul> </div>
複製代碼

②.用字典模板向首頁傳遞參數並完成發佈詳情頁前端html

(1)首頁列表顯示所有問答:

    將數據庫查詢結果傳遞到前端頁面 

'fabus': Fabu.query.all()

(2)前端頁面循環顯示整個列表。

{% for foo in fabus %}
    {{ foo.author.username }}
    {{ foo.title }}
    {{ foo.creat_time }}
    {{ foo.detail }}
{% endfor %}

(3)問答排序

order_by('-creat_time')

(4)完成問答詳情頁佈局:

    包含問答的所有信息

    評論區

    以往評論列表顯示區。

(5)在首頁點擊問答標題,連接到相應詳情頁。

                            <h4 class="text-center"><a href="{{ url_for('fabuview',fabu_id=foo.id) }}">{{ foo.title }}</a></h4>
# 跳轉發布詳情 @app.route('/fabuview/<fabu_id>') # 和idea的update同樣,將id帶到控制器 def fabuview(fabu_id): fa = Fabu.query.filter(Fabu.id == fabu_id).first() # 根據主頁帶回來的id查詢出整條元組記錄,丟進fa comments = Comment.query.filter(Comment.fabu_id == fabu_id).all() # 根據帶回來的Fabu的id在Comment查詢出全部評論 return render_template('fabuview.html', fa=fa, comments=comments) # 把值fa丟進鍵fa,在fabuview.html頁面調用

十二、從首頁問答列表標題連接到詳情頁

①.首頁標題的標籤作帶參數的連接。

href="{{ url_for('fabuview',fabu_id=foo.id) }}"

②.主PY文件寫視圖函數,帶id參數。

# 跳轉發布詳情 @app.route('/fabuview/<fabu_id>') # 和idea的update同樣,將id帶到控制器 def fabuview(fabu_id): fa = Fabu.query.filter(Fabu.id == fabu_id).first() # 根據主頁帶回來的id查詢出整條元組記錄,丟進fa comments = Comment.query.filter(Comment.fabu_id == fabu_id).all() # 根據帶回來的Fabu的id在Comment查詢出全部評論 return render_template('fabuview.html', fa=fa, comments=comments) # 把值fa丟進鍵fa,在fabuview.html頁面調用

③.在詳情頁將數據顯示在恰當的位置,即調用後端字典模型。

{{ fa.title }}
{{ fa.author.username }}
{{ fa.creat_time }}
{{ fa.detail }}

1三、實現發佈評論,並顯示評論區

①.前端html模板。

<div>

<textarea></textarea>

<button></button>

</div>

②.後臺視圖函數

複製代碼
# 跳轉評論 @app.route('/comment/', methods=['POST']) @loginFirst # 裝飾器,跳轉某頁面以前先進行登陸 def comment(): detail = request.form.get('pinglun') # post請求模式,安排對象接收數據 author_id = User.query.filter(User.username == session.get('user')).first().id fabu_id = request.form.get('fa_id') comment = Comment(detail=detail, author_id=author_id, fabu_id=fabu_id) # 將對象接收的數據賦到Comment類中,即存到數據庫 db.session.add(comment) # 執行操做 db.session.commit() # 提交到數據庫 return redirect(url_for('fabuview', fabu_id=fabu_id)) # 重定向到fabuview請求時要帶fabu_id
複製代碼

③.顯示評論條數

其實相似於首頁顯示發佈內容

{% for foo in fa.comments %}
    {{ foo.author.username }}
    {{ foo.creat_time }}
    {{ foo.detail }}
{% endfor %}

1四、完成我的中心相關信息

①.我的中心—視圖函數帶標籤頁面參數tag(在if判斷時判斷tag,能夠三個頁面跳轉同一請求函數)

複製代碼
# 跳轉用戶詳情 @app.route('/yonghu/<username_id>/<tag>') # 爲了把頁面分開,咱們在html頁面傳了一個tag參數 def yonghu(username_id, tag): user = User.query.filter(User.id == username_id).first() context = { 'userid': user.id, 'username': user.username, 'fabus': user.fabu, 'comments': user.comments } # 根據tag的不一樣去到不一樣頁面,一個請求跳轉3個不一樣頁面 if tag == '1': return render_template('yonghu1.html', **context) elif tag == '2': return render_template('yonghu2.html', **context) else: return render_template('yonghu3.html', **context)
複製代碼

②.我的中心—導航標籤連接增長tag參數

        <ul class="nav nav-pills"> <li class="active" role="presentation"><a href="{{ url_for('yonghu',username_id=userid,tag=1) }}">我的信息</a></li> <li class="active" role="presentation"><a href="{{ url_for('yonghu',username_id=userid,tag=2) }}">發佈信息</a></li> <li class="active" role="presentation"><a href="{{ url_for('yonghu',username_id=userid,tag=3) }}">評論信息</a></li> </ul>

③.我的信息,發佈信息,評論信息等頁面所有繼承到我的中心頁,我的中心頁再繼承到首頁

(1)我的中心頁:

{% block yonghubody %}{% endblock %}

(2)我的信息,發佈信息,評論信息頁:

{% block yonghubody %}我的信息內容html{% endblock %}
{% block yonghubody %}發佈信息內容html{% endblock %}
{% block yonghubody %}評論信息內容html{% endblock %}

④.我的中心—有連接到我的中心頁面的url增長tag參數

<a href="{{ url_for('yonghu',username_id=foo.author_id,tag=1) }}">

1五、實現導航條中的搜索功能

①.搜索輸入框method爲‘get’

<form class="form-inline" role="form" action="{{ url_for('search') }}" method="get">
</form>

②完成視圖函數search()

from sqlalchemy import or_, and_
複製代碼
# 跳轉首頁搜索 @app.route('/search/') def search(): sousuo = request.args.get('sousuo') # args獲取關鍵字,區別form fabus = Fabu.query.filter( or_( # 兩種查詢條件 Fabu.title.contains(sousuo), # contains模糊查  Fabu.detail.contains(sousuo) ) ).order_by('-creat_time') return render_template('daohang.html', fabus=fabus) # fabus要和原首頁數據模型同樣
複製代碼

 1六、密碼保護

複製代碼
from werkzeug.security import generate_password_hash,check_password_hash _password = db.Column(db.String(200), nullable=False) # 密碼加密內部使用  @property # 定義函數,須要用屬性時能夠用函數代替 def password(self): # 密碼加密外部使用 return self._password @password.setter def password(self,row_password): # 密碼進來時進行加密,generate_password_hash是一個密碼加鹽哈希函數,生成的哈希值可經過check_password_hash()進行驗證。 self._password = generate_password_hash(row_password) def check_password(self,row_password): # check_password_hash函數用於驗證通過generate_password_hash哈希的密碼。若密碼匹配,則返回真,不然返回假。 result = check_password_hash(self._password,row_password) return result
複製代碼
密碼進來時進行加密,generate_password_hash是一個密碼加鹽哈希函數,生成的哈希值可經過check_password_hash()進行驗證。
check_password_hash函數用於驗證通過generate_password_hash哈希的密碼。若密碼匹配,則返回真,不然返回假。

登陸驗證:

把user.password ==passwodr,修改爲user.check_password(password):  # 判斷密碼
複製代碼
# 跳轉登錄。 @app.route('/denglu/', methods=['GET', 'POST']) # methods定義它有兩種請求方式 def denglu(): if request.method == 'GET': return render_template('denglu.html') else: username = request.form.get('user') # post請求模式,安排對象接收數據 password = request.form.get('pass') user = User.query.filter(User.username == username).first() # 做查詢,並判斷 if user: # 判斷用戶名 if user.check_password(password): # 判斷密碼 session['user'] = username # 利用session添加傳回來的值username session.permanent = True # 設置session過時的時間 return redirect(url_for('daohang')) else: return u'用戶密碼錯誤' else: return u'用戶不存在,請先註冊'
複製代碼

1七、模型分離

爲了方便管理,咱們進行模型分離

主py:

複製代碼
from flask import Flask, render_template, request, redirect, url_for, session import config from functools import wraps from sqlalchemy import or_, and_ from models import User,Fabu,Comment from exts import db app = Flask(__name__) # 建立Flask對象 app.config.from_object(config) # 關聯config.py文件進來 db.init_app(app) # 創建和數據庫的關係映射
複製代碼

models.py:

複製代碼
from datetime import datetime from werkzeug.security import generate_password_hash,check_password_hash from exts import db class User(db.Model): # 建立類User __tablename__ = 'user' # 類對應的表名user id = db.Column(db.Integer, primary_key=True, autoincrement=True) # autoincrement自增加 username = db.Column(db.String(20), nullable=False) # nullable是否爲空 _password = db.Column(db.String(200), nullable=False) # 密碼加密內部使用 nickname = db.Column(db.String(20), nullable=True) @property # 定義函數,須要用屬性時能夠用函數代替 def password(self): # 密碼加密外部使用 return self._password @password.setter def password(self,row_password): # 密碼進來時進行加密,generate_password_hash是一個密碼加鹽哈希函數,生成的哈希值可經過check_password_hash()進行驗證。 self._password = generate_password_hash(row_password) def check_password(self,row_password): # check_password_hash函數用於驗證通過generate_password_hash哈希的密碼。若密碼匹配,則返回真,不然返回假。 result = check_password_hash(self._password,row_password) return result class Fabu(db.Model): __tablename__ = 'fabu' id = db.Column(db.Integer, primary_key=True, autoincrement=True) title = db.Column(db.String(100), nullable=False) detail = db.Column(db.Text, nullable=False) creat_time = db.Column(db.DateTime, default=datetime.now) # 提交時間會本身賦值 author_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 數據類型是db.Integer,db.ForeignKey參數指定外鍵是哪一個表中哪一個id author = db.relationship('User', backref=db.backref('fabu')) # 創建關聯,其author屬性將返回與問答相關聯的用戶實例,至關於數據庫中的錶鏈接 # 第一個參數代表這個關係的另外一端是哪一個類,第二個參數backref,將向User類中添加一個fabu屬性,從而定義反向關係,這一屬性可訪問Fabu類,獲取的是模型對象 class Comment(db.Model): __tablename__ = 'comment' id = db.Column(db.Integer, primary_key=True, autoincrement=True) author_id = db.Column(db.Integer, db.ForeignKey('user.id')) fabu_id = db.Column(db.Integer, db.ForeignKey('fabu.id')) creat_time = db.Column(db.DateTime, default=datetime.now) detail = db.Column(db.Text, nullable=False) fabu = db.relationship('Fabu', backref=db.backref('comments', order_by=creat_time.desc)) # order_by=creat_time.desc按時間降序 author = db.relationship('User', backref=db.backref('comments')) # db.create_all() # 測試是否鏈接成功
複製代碼

exts.py:

from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() # 創建和數據庫的關係映射

這裏引進多一個exts.py主要使models.py和主py不要進入死循環狀態

(備註:在這裏小編髮現一個問題,模型分離要在數據庫表建出後分離,刪除數據庫表或換機後不會自動再建立表,頁面出現報錯,也就是說只能在數據庫表不變更下使用它,可能因爲小編是菜鳥,暫時沒有找到解決方法,慎用)

1八、數據遷移

數據遷移應用於模型增長屬性刪除屬性,增長模型刪除模型或修改屬性數據類型時使用,能夠極大程度方便咱們的操做,例如在刪除模型時不用去數據庫刪除表格再從新運行,修改模型屬性數據類型時不會出現數據刪除後重建等麻煩。

manage.py:

複製代碼
from flask_script import Manager from flask_migrate import Migrate,MigrateCommand # flask_migrate是一個數據遷移框架,須要經過flask_script來操做 from untitled import db from untitled import app from untitled import User, Fabu, Comment manager = Manager(app) # Manager只有一個參數:一個Flask實例 migrate = Migrate(app, db) # 使用Migrate綁定app和db # 添加遷移腳本命令 manager.add_command('db',MigrateCommand) # 加入命令,命令行輸入python manage.py db migrate if __name__ == '__main__': manager.run() # 啓動Manager實例接收命令行中的命令 ''' 生成初始化遷移環境,只運行一次 python manage.py db init 生成遷移文件,模型改變了須要執行 python manage.py db migrate 映射到數據庫表中 python manage.py db upgrade '''
複製代碼

nick是新增的屬性

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息