一步步講解利用Flask開發(fā)一個(gè)Web程序
開發(fā)環(huán)境 : Linux系統(tǒng),語(yǔ)言: Python,Html, Css
利用Flask實(shí)現(xiàn)一個(gè)WatchList的Web程序,部分代碼和圖片都是來自:Flask 入門教程,我在此基礎(chǔ)上修改了一下,最后的效果如下:
1. 安裝 Flask和一些基本插件
pip install flask pip install Flask-SQLAlchemy pip install pymysql
如果安裝比較慢的話,可以加上 -i https://pypi.tsinghua.edu.cn/simple
2. 創(chuàng)建項(xiàng)目結(jié)構(gòu)
創(chuàng)建一個(gè)文件夾來存放你的項(xiàng)目文件。項(xiàng)目的基本結(jié)構(gòu)如下:
WatchList/{static/images style.css} {template/index.html login.html} app.py
3.在WatchList目錄下創(chuàng)建虛擬環(huán)境并進(jìn)入虛擬環(huán)境
python3 -m venv env scoure ./env/Scripts/activate
4. 編寫主應(yīng)用文件 (app.py)
在 WatchList目錄下創(chuàng)建一個(gè)名為 app.py
的文件,并編寫以下代碼:
from flask import Flask, render_template, url_for, redirect, request, flash from flask_sqlalchemy import SQLAlchemy import click app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@localhost/watchlist' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.secret_key = 'your_secret_key' # 用于閃現(xiàn)消息 db = SQLAlchemy(app) # 創(chuàng)建數(shù)據(jù)庫(kù)命令 @app.cli.command() def forge(): """Generate fake data.""" db.create_all() name = 'BrokenOfViolet' movies = [ {'title': 'My Neighbor Totoro', 'year': '1988'}, {'title': 'Dead Poets Society', 'year': '1989'}, {'title': 'A Perfect World', 'year': '1993'}, {'title': 'Leon', 'year': '1994'}, {'title': 'Mahjong', 'year': '1996'}, {'title': 'Swallowtail Butterfly', 'year': '1996'}, {'title': 'King of Comedy', 'year': '1999'}, {'title': 'Devils on the Doorstep', 'year': '1999'}, {'title': 'WALL-E', 'year': '2008'}, {'title': 'The Pork of Music', 'year': '2012'}, ] user = User(username=name, password='password123') # 設(shè)定一個(gè)默認(rèn)密碼 db.session.add(user) for m in movies: movie = Movie(title=m['title'], year=m['year']) db.session.add(movie) db.session.commit() click.echo('Done.') # 數(shù)據(jù)庫(kù)模型 class User(db.Model): username = db.Column(db.String(20), primary_key=True) password = db.Column(db.String(20)) class Movie(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(60)) year = db.Column(db.String(4)) # 主頁(yè)路由 @app.route('/') def index(): user = User.query.first() # 修復(fù)此處變量名 movies = Movie.query.all() return render_template("index.html", user=user, movies=movies) # 404 錯(cuò)誤處理路由 @app.errorhandler(404) def page_not_found(e): user = User.query.first() return render_template('404.html', user=user), 404 # 登錄路由 @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] user = User.query.filter_by(username=username).first() # 比對(duì)用戶輸入的密碼和數(shù)據(jù)庫(kù)中存儲(chǔ)的密碼 if user and user.password == password: flash('Login successful!', 'success') return redirect(url_for('index')) # 假設(shè)登錄成功后重定向到index else: flash('Invalid username or password.', 'danger') return render_template('login.html') if __name__ == '__main__': app.run(debug=True)
5. 創(chuàng)建 HTML 模板文件
主頁(yè)templates/index.html
在 templates
目錄中創(chuàng)建一個(gè)名為 index.html
的文件,編寫一個(gè)簡(jiǎn)單的 HTML 頁(yè)面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="{{url_for('static',filename='style.css')}}" rel="external nofollow" type="text/css"> <title>{{ name }}'s Watchlist</title> </head> <body> <h2>{{ name }}'s Watchlist <img alt="Avatar" class="avator" src="{{url_for('static',filename='images/avatar.png')}}"> </h2> {# 使用 length 過濾器獲取 movies 變量的長(zhǎng)度 #} <p>{{ movies|length }} Titles</p> <ul class="movie-list"> {% for movie in movies %} {# 迭代 movies 變量 #} <li>{{ movie.title }} - {{ movie.year }}</li> {# 等同于 movie['title'] #} {% endfor %} {# 使用 endfor 標(biāo)簽結(jié)束 for 語(yǔ)句 #} </ul> <img alt="Totoro" class="totoro" src="{{url_for('static',filename='images/totoro.gif')}}" </body> </html>
登陸界面templates/login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login</title> <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" rel="external nofollow" > </head> <body> <div class="login-container"> <h2>Login</h2> {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} <ul class="flashes"> {% for category, message in messages %} <li class="{{ category }}">{{ message }}</li> {% endfor %} </ul> {% endif %} {% endwith %} <form method="post" action="{{ url_for('login') }}"> <div class="input-group"> <label for="username">Username</label> <input type="text" id="username" name="username" required> </div> <div class="input-group"> <label for="password">Password</label> <input type="password" id="password" name="password" required> </div> <button type="submit">Login</button> </form> </div> </body> </html>
6. 創(chuàng)建靜態(tài)文件 (static/style.css)
在 static
目錄中創(chuàng)建一個(gè)名為 style.css
的文件,添加一些簡(jiǎn)單的 CSS 樣式:
/* 頁(yè)面整體 */ body { font-family: Arial, sans-serif; background-color: #f0f0f0; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } /* 頁(yè)腳 */ footer { color: #888; margin-top: 15px; text-align: center; padding: 10px; } /* 頭像 */ .avatar { width: 40px; } /* 電影列表 */ .movie-list { list-style-type: none; padding: 0; margin-bottom: 10px; box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); } .movie-list li { padding: 12px 24px; border-bottom: 1px solid #ddd; } .movie-list li:last-child { border-bottom:none; } .movie-list li:hover { background-color: #f8f9fa; } /* 龍貓圖片 */ .totoro { display: block; margin: 0 auto; height: 100px; } .login-container { background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); width: 300px; text-align: center; } h2 { margin-bottom: 20px; } .input-group { margin-bottom: 15px; text-align: left; } .input-group label { display: block; margin-bottom: 5px; } .input-group input { width: 100%; padding: 8px; box-sizing: border-box; } button { width: 100%; padding: 10px; background-color: #007BFF; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; } button:hover { background-color: #0056b3; } .flashes { list-style-type: none; padding: 0; } .flashes li { padding: 10px; margin-bottom: 10px; border-radius: 5px; } .flashes li.success { background-color: #d4edda; color: #155724; } .flashes li.danger { background-color: #f8d7da; color: #721c24; }
7. 運(yùn)行應(yīng)用
在終端中,導(dǎo)航到 WatchList 目錄并運(yùn)行應(yīng)用。因?yàn)樵赼pp.py中定義了forge函數(shù)用于提交數(shù)據(jù),所以進(jìn)行如下操作:
flask forge
最后直接運(yùn)行 app.py 或者執(zhí)行 flask run
總結(jié)
到此這篇關(guān)于利用Flask開發(fā)一個(gè)Web程序的文章就介紹到這了,更多相關(guān)Flask開發(fā)Web程序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于TensorBoard的使用以及遇到的坑記錄
這篇文章主要介紹了關(guān)于TensorBoard的使用以及遇到的坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09python 獲取字典鍵值對(duì)的實(shí)現(xiàn)
這篇文章主要介紹了python 獲取字典鍵值對(duì)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11python3+PyQt5實(shí)現(xiàn)文檔打印功能
這篇文章主要為大家詳細(xì)介紹了python3+PyQt5實(shí)現(xiàn)文檔打印功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04python中readline判斷文件讀取結(jié)束的方法
這篇文章主要介紹了python中readline判斷文件讀取結(jié)束的方法,實(shí)例形式詳細(xì)分析了Python中readline的用法,需要的朋友可以參考下2014-11-11Python中元組的基礎(chǔ)介紹及常用操作總結(jié)
元組是一種不可變序列。元組變量的賦值要在定義時(shí)就進(jìn)行,這就像C語(yǔ)言中的const變量或是C++的引用,定義時(shí)賦值之后就不允許有修改。元組存在的意義是:元組在映射中可以作為鍵使用,因?yàn)橐WC鍵的不變性。元組作為很多內(nèi)置函數(shù)和方法的返回值存在2021-09-09使用Python的Tornado框架實(shí)現(xiàn)一個(gè)一對(duì)一聊天的程序
這篇文章主要介紹了使用Python的Tornado框架實(shí)現(xiàn)一個(gè)一對(duì)一聊天的程序,程序基于WebSocket,需要的朋友可以參考下2015-04-04