Flask实战----做了一个简易版CSDN
Flask實戰
- 數據庫設計
- 創建數據表
- 創建數據庫操作類
- exc_info()
- Python操作MySQL基本用法
- 創建表單類
- 實現登錄功能
- 博客列表功能實現
- 添加博客功能實現
數據庫設計
創建數據表
需要創建兩個數據表
- users:`用戶表,用于存儲用戶信息
- articles:博客表,用于存儲博客信息
下面以創建users為例:
//如果存在重名的將其刪去 DROP TABLE IF EXISTS `articles`; CREATE TABLE `articles` (`id` int NOT NULL AUTO_INCREMENT,`title` varchar(255) DEFAULT NULL,`content` text,`author` varchar(255) DEFAULT NULL,`create_date` datetime DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;- drop table if exists:一般drop table if exists是數據庫里面的,后面接表名如:drop table if exists xxx_book意思就是:如果數據庫中存在xxx_book表,就把它從數據庫中drop掉。備份sql中一般都有這樣的語句,如果是數據庫中有這個表,先drop掉,然后create表,然后再進行數據插入。
- AUTO_INCREMENT:代表值自動增加,只有主鍵可以添加
- ENGINE=InnoDB:使用baiinnobd引擎。
- CHARSET=utf8:數據庫默認編碼格式為utf8.
### MySQL基本操作
MySQL基本操作
創建數據庫操作類
為了復用代碼,以及使用的安全性,我們一般會創建一個`myspl_util.py`文件,文件中包含一個`MysqlUtil`類。 import pymysql # 引入pymysql模塊 import traceback # 引入python中的traceback模塊,跟蹤錯誤 import sys # 引入sys模塊class MysqlUtil():def __init__(self):# 初始化方法,連接數據庫host = 'localhost' # 主機名user = 'root' # 數據庫用戶名password = '******' # 數據庫密碼database = 'notebook' # 數據庫名稱self.db = pymysql.connect(host=host,user=user,password=password,db=database) # 建立連接self.cursor = self.db.cursor(cursor=pymysql.cursors.DictCursor) # 設置游標,并將游標設置為字典類型def insert(self, sql):'''插入數據庫sql:插入數據庫的sql語句'''try:# 執行sql語句self.cursor.execute(sql)# 提交到數據庫執行self.db.commit()except Exception: # 方法一:捕獲所有異常# 如果發生異常,則回滾print("發生異常", Exception)self.db.rollback()finally:# 最終關閉數據庫連接self.db.close()def fetchone(self, sql):'''查詢數據庫:單個結果集fetchone(): 該方法獲取下一個查詢結果集。結果集是一個對象'''try:# 執行sql語句self.cursor.execute(sql)result = self.cursor.fetchone()except: # 方法二:采用traceback模塊查看異常# 輸出異常信息traceback.print_exc()# 如果發生異常,則回滾self.db.rollback()finally:# 最終關閉數據庫連接self.db.close()return resultdef fetchall(self, sql):'''查詢數據庫:多個結果集fetchall(): 接收全部的返回結果行.'''try:# 執行sql語句self.cursor.execute(sql)results = self.cursor.fetchall()except: # 方法三:采用sys模塊回溯最后的異常# 輸出異常信息info = sys.exc_info()print(info[0], ":", info[1])# 如果發生異常,則回滾self.db.rollback()finally:# 最終關閉數據庫連接self.db.close()return resultsdef delete(self, sql):'''刪除結果集'''try:# 執行sql語句self.cursor.execute(sql)self.db.commit()except: # 把這些異常保存到一個日志文件中,來分析這些異常# 將錯誤日志輸入到目錄文件中f = open("\log.txt", 'a')traceback.print_exc(file=f)f.flush()f.close()# 如果發生異常,則回滾self.db.rollback()finally:# 最終關閉數據庫連接self.db.close()#以下省略更新功能- traceback.print_exc(): 將錯誤信息在終端輸出
- traceback.print_exc(file=f):可以將錯誤打印在文本中,f為文件類對象。
- flush():flush() 方法是用來刷新緩沖區的,即將緩沖區中的數據立刻寫入文件,同時清空緩沖區,不需要是被動的等待輸出緩沖區寫入。
一般情況下,文件關閉后會自動刷新緩沖區,但有時你需要在關閉前刷新它,這時就可以使用 flush() 方法。 - commit():涉及到更改數據表中的內容,都要在處理之后使用該方法。
exc_info()
exc_info() 方法會將當前的異常信息以元組的形式返回,該元組中包含 3 個元素,分別為 type、value 和 traceback,它們的含義分別是:Python操作MySQL基本用法
Python操作MySQL
下邊的內容涉及到的Flask知識點較多,可以先看下面這兩篇博客。
# 用戶登錄功能實現
創建表單類
from wtforms import Form, StringField, TextAreaField, PasswordField from wtforms.validators import DataRequired,Length,ValidationError from flask_wtf import FlaskForm # 導入我么自己創建的 操作數據庫的類 from mysql_util import MysqlUtil# Register Form Class class LoginForm(FlaskForm):username = StringField('用戶名',validators=[DataRequired(message='請輸入用戶名'),Length(min=2, max=25,message='長度在4-25個字符之間')])password = PasswordField('密碼',validators = [DataRequired(message='密碼不能為空'),Length(min=6,max=20,message='長度在6-20個字符之間'),])def validate_username(self,field):sql = "SELECT * FROM users WHERE username = '%s'" % (field.data) # 根據用戶名查找user表中記錄db = MysqlUtil() # 實例化數據庫操作類result = db.fetchone(sql) # 獲取一條記錄if not result:raise ValidationError("用戶名不存在")上述代碼中,在Login Form中定義了useame和password字段,它們分別對應著登錄頁面表單中的用戶名和密碼。
此外,還使用validate多段名函數對usermame字段添加自定義驗證規則,判斷用戶名是否存在。
實現登錄功能
當用戶填寫登錄信息后,如果驗證全部通過,需要將登錄標識和username寫入Session中,為后面判斷用戶是否登錄做準備。此外,還需要在用戶訪問/logm路由時,判斷用戶是否已經登錄。如果用
戶之前已經登錄過,那么則不需要再次登錄,而是直接跳轉到控制臺。
**解釋:**通過requset.form可以直接提取請求體中的表單格式的數據, 是一個類字典的對象,所以可以通過request.form['username']獲得表單中字段為username對應的數據。
sha256_crypt.verify()解釋:verify()方法第一個參數是用戶1輸入的密碼,第二個參數是數據庫加密后的密碼,如果返回True,則表示密碼相同。
session['logged_in'] = True解釋:Session對象是一個字典對象,包含會話變量和關聯值的鍵值對。在進行上述設置后,就可以在其余函數中采用session.get('logged_in'),即字典取值的方法判斷用戶是否已經登錄。
flash('登錄成功!', 'success') # 閃存信息**解釋:**是用來閃現需要顯示給用戶的內容,上面寫入后,可以在需要讀取的地方進行讀取,如
{% for message in get_flashed_messages() %}<div class=flash>{{ message }}</div>{% endfor %} return render_template('login.html',form=form)**解釋:**通過將表單類參數傳入模板,在模板中生成一個表單。
# 用戶權限管理功能實現 對于需要用戶登錄后才能訪問的路由,我們可以實現一個裝飾器。 def is_logged_in(f):@wraps(f)def wrap(*args, **kwargs):if 'logged_in' in session: # 判斷用戶是否登錄return f(*args, **kwargs) # 如果登錄,繼續執行被裝飾的函數else: # 如果沒有登錄,提示無權訪問flash('無權訪問,請先登錄', 'danger')return redirect(url_for('login'))return wrap
- 裝飾器的作用: 在不改變原有功能代碼的基礎上,添加額外的功能,如用戶驗證等。
- @wraps(view_func)的作用: 不改變使用裝飾器原有函數的結構(如name, doc)
- 需要導入庫:from functools import wraps
- *args:表示任何多個無名參數,它是一個tuple
- **kwargs:表示關鍵字參數,它是一個dict
# 博客模塊設計
博客列表功能實現
@app.route('/dashboard') @is_logged_in def dashboard():db = MysqlUtil() # 實例化數據庫操作類sql = "SELECT * FROM articles WHERE author = '%s' ORDER BY create_date DESC" % (session['username']) # 根據用戶名查找用戶筆記信息result = db.fetchall(sql) # 查找所有筆記if result: # 如果筆記存在,賦值給articles變量return render_template('dashboard.html', articles=result)else: # 如果筆記不存在,提示暫無筆記msg = '暫無筆記信息'return render_template('dashboard.html', msg=msg) session['username']**解釋:**因為在這之前用戶已經登錄成功,所以可以用上述方法來獲取用戶名。
添加博客功能實現
@app.route('/add_article', methods=['GET', 'POST']) @is_logged_in def add_article():form = ArticleForm(request.form) # 實例化ArticleForm表單類if request.method == 'POST' and form.validate(): # 如果用戶提交表單,并且表單驗證通過# 獲取表單字段內容title = form.title.datacontent = form.content.dataauthor = session['username']create_date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())db = MysqlUtil() # 實例化數據庫操作類sql = "INSERT INTO articles(title,content,author,create_date) \VALUES ('%s', '%s', '%s','%s')" % (title,content,author,create_date) # 插入數據的SQL語句db.insert(sql)flash('創建成功', 'success') # 閃存信息return redirect(url_for('dashboard')) # 跳轉到控制臺return render_template('add_article.html', form=form) # 渲染模板 request.method == 'POST' and form.validate():解釋:validate是驗證數據的意思
所以from.validate_on_submit()等價于request.method==' post ' and from.validate()
效果:
.詳細代碼可以在評論區留言哦
- FastAPI ------框架基礎
- python前端學習-----Flask進階
總結
以上是生活随笔為你收集整理的Flask实战----做了一个简易版CSDN的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 单调队列(一套模板通吃)
- 下一篇: c++ map通过值找键与通过键找值得方