一步步講解利用Flask開發(fā)一個Web程序
開發(fā)環(huán)境 : Linux系統(tǒng),語言: Python,Html, Css
利用Flask實現(xiàn)一個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)建項目結(jié)構(gòu)
創(chuàng)建一個文件夾來存放你的項目文件。項目的基本結(jié)構(gòu)如下:
WatchList/{static/images style.css} {template/index.html login.html} app.py3.在WatchList目錄下創(chuàng)建虛擬環(huán)境并進入虛擬環(huán)境
python3 -m venv env scoure ./env/Scripts/activate
4. 編寫主應(yīng)用文件 (app.py)
在 WatchList目錄下創(chuàng)建一個名為 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ù)庫命令
@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è)定一個默認密碼
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ù)庫模型
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))
# 主頁路由
@app.route('/')
def index():
user = User.query.first() # 修復(fù)此處變量名
movies = Movie.query.all()
return render_template("index.html", user=user, movies=movies)
# 404 錯誤處理路由
@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()
# 比對用戶輸入的密碼和數(shù)據(jù)庫中存儲的密碼
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 模板文件
主頁templates/index.html
在 templates 目錄中創(chuàng)建一個名為 index.html 的文件,編寫一個簡單的 HTML 頁面:
<!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 變量的長度 #}
<p>{{ movies|length }} Titles</p>
<ul class="movie-list">
{% for movie in movies %} {# 迭代 movies 變量 #}
<li>{{ movie.title }} - {{ movie.year }}</li> {# 等同于 movie['title'] #}
{% endfor %} {# 使用 endfor 標簽結(jié)束 for 語句 #}
</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)建一個名為 style.css 的文件,添加一些簡單的 CSS 樣式:
/* 頁面整體 */
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
/* 頁腳 */
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īng)用
在終端中,導(dǎo)航到 WatchList 目錄并運行應(yīng)用。因為在app.py中定義了forge函數(shù)用于提交數(shù)據(jù),所以進行如下操作:
flask forge
最后直接運行 app.py 或者執(zhí)行 flask run

總結(jié)
到此這篇關(guān)于利用Flask開發(fā)一個Web程序的文章就介紹到這了,更多相關(guān)Flask開發(fā)Web程序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于TensorBoard的使用以及遇到的坑記錄
這篇文章主要介紹了關(guān)于TensorBoard的使用以及遇到的坑記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
python中readline判斷文件讀取結(jié)束的方法
這篇文章主要介紹了python中readline判斷文件讀取結(jié)束的方法,實例形式詳細分析了Python中readline的用法,需要的朋友可以參考下2014-11-11
Python中元組的基礎(chǔ)介紹及常用操作總結(jié)
元組是一種不可變序列。元組變量的賦值要在定義時就進行,這就像C語言中的const變量或是C++的引用,定義時賦值之后就不允許有修改。元組存在的意義是:元組在映射中可以作為鍵使用,因為要保證鍵的不變性。元組作為很多內(nèi)置函數(shù)和方法的返回值存在2021-09-09
使用Python的Tornado框架實現(xiàn)一個一對一聊天的程序
這篇文章主要介紹了使用Python的Tornado框架實現(xiàn)一個一對一聊天的程序,程序基于WebSocket,需要的朋友可以參考下2015-04-04

