Skip to content

Commit 456cb1a

Browse files
First commit
0 parents  commit 456cb1a

25 files changed

+591
-0
lines changed

.flaskenv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
FLASK_ENV=development
2+
FLASK_APP=watchlist

requirements.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Click==7.0
2+
coverage==5.1
3+
Flask==1.1.1
4+
Flask-Login==0.4.1
5+
Flask-SQLAlchemy==2.4.0
6+
itsdangerous==1.1.0
7+
Jinja2==2.10.1
8+
MarkupSafe==1.1.1
9+
python-dotenv==0.10.3
10+
SQLAlchemy==1.3.6
11+
Werkzeug==0.15.4

watchlist/__init__.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import sys
2+
import os
3+
from flask import Flask
4+
from flask_sqlalchemy import SQLAlchemy
5+
from flask_login import LoginManager
6+
7+
8+
# SQLite URI compatible
9+
WIN = sys.platform.startswith('win')
10+
if WIN:
11+
prefix = 'sqlite:///'
12+
else:
13+
prefix = 'sqlite:////'
14+
15+
16+
17+
18+
app = Flask(__name__)
19+
# os.getenv('SECRET_KEY', 'dev') 表示读取系统环境变量 SECRET_KEY 的值,如果没有获取到,则使用 dev
20+
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'dev')
21+
# 注意更新这里的路径,把 app.root_path 添加到 os.path.dirname() 中
22+
# 以便把文件定位到项目根目录
23+
app.config['SQLALCHEMY_DATABASE_URI'] = prefix + os.path.join(os.path.dirname(app.root_path),os.getenv('DATABASE_FILE', 'data.db'))
24+
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
25+
26+
db = SQLAlchemy(app)
27+
login_manager = LoginManager(app)
28+
29+
# 除了实例化扩展类之外,我们还要实现一个“用户加载回调函数”
30+
@login_manager.user_loader
31+
def load_user(user_id): # 创建用户加载回调函数,接受用户 ID 作为参数
32+
from watchlist.models import User
33+
user = User.query.get(int(user_id)) # 用 ID 作为 User 模型的主键查询对应的用户
34+
return user # 返回用户对象
35+
36+
37+
38+
# 未登录用户访问delete等页面时,我们不能让他访问,我们要让他重定向,重定向到哪里?就在这里决定
39+
# 登录视图端点(函数名)
40+
login_manager.login_view='login'
41+
42+
43+
44+
@app.context_processor
45+
def inject_user():
46+
from watchlist.models import User
47+
user = User.query.first()
48+
return dict(user=user)
49+
# 这个函数返回的变量(以字典键值对的形式)将会统一注入到每一个模板的上下文环境中,因此可以直接在模板中使用。
50+
51+
52+
from watchlist import views,errors,commands
53+
54+
55+
56+
57+
58+
59+
60+
61+
62+
63+
64+
65+
66+
67+
68+
69+
70+
71+
72+
73+
74+
1.17 KB
Binary file not shown.
1.88 KB
Binary file not shown.
717 Bytes
Binary file not shown.
1.16 KB
Binary file not shown.
2.92 KB
Binary file not shown.

watchlist/commands.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import click
2+
3+
from watchlist import app,db
4+
from watchlist.models import User,Movie
5+
6+
@app.cli.command()
7+
@click.option('--drop',is_flag=True,help='Create after drop')
8+
def initdb(drop):
9+
"""Initialize the database"""
10+
if drop: # 判断是否输入了选项
11+
db.drop_all()
12+
db.create_all()
13+
click.echo('Initialize database.') #输出提示信息
14+
15+
16+
@app.cli.command()
17+
def forge():
18+
"""Generate fake data"""
19+
# 如果没有db.drop_all(),那么,就在数据库原有的两张表的基础上,继续添加记录
20+
db.create_all()
21+
name = 'alpha2'
22+
movies = [
23+
{'title': 'My Neighbor Totoro', 'year': '1988'},
24+
{'title': 'Dead Poets Society', 'year': '1989'},
25+
{'title': 'A Perfect World', 'year': '1993'},
26+
{'title': 'Leon', 'year': '1994'},
27+
{'title': 'Mahjong', 'year': '1996'},
28+
{'title': 'Swallowtail Butterfly', 'year': '1996'},
29+
{'title': 'King of Comedy', 'year': '1999'},
30+
{'title': 'Devils on the Doorstep', 'year': '1999'},
31+
{'title': 'WALL-E', 'year': '2008'},
32+
{'title': 'The Pork of Music', 'year': '2012'},
33+
{'title': 'Harry Potter', 'year': '2012'},
34+
{'title': '我和我的家乡', 'year': '2020'},
35+
]
36+
37+
user = User(name=name)
38+
db.session.add(user)
39+
for m in movies:
40+
movie = Movie(title=m['title'],year=m['year'])
41+
db.session.add(movie)
42+
db.session.commit()
43+
click.echo('Done.')
44+
45+
46+
47+
@app.cli.command()#注册为命令
48+
@click.option('--userName',prompt=True,help='login user name')
49+
@click.option('--password',prompt=True,hide_input=True,confirmation_prompt=True,help='login user password')
50+
def admin(username,password):
51+
db.create_all()
52+
user = User.query.first()
53+
if user is not None:
54+
click.echo('更新用户名...')
55+
user.username = username
56+
user.set_password(password)
57+
58+
else:
59+
click.echo('创建新用户...')
60+
user = User(username=username,name='Admin')
61+
user.set_password(password)
62+
db.session.add(user)
63+
64+
db.session.commit()
65+
click.echo('Done.')

watchlist/errors.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from flask import render_template
2+
from watchlist import app
3+
4+
# 使用 app.errorhandler() 装饰器注册一个错误处理函数
5+
@app.errorhandler(404) # 传入要处理的错误代码
6+
def page_not_found(e): # 接受异常对象作为参数
7+
# user = User.query.first()
8+
return render_template('errors/404.html'),404 # 返回模板和状态码
9+
# 普通的视图函数之所以不用写出状态码,是因为默认会使用 200 状态码,表示成功
10+
11+
12+
@app.errorhandler(400)
13+
def bad_request(e):
14+
return render_template('errors/400.html'), 400
15+
16+
17+
@app.errorhandler(500)
18+
def internal_server_error(e):
19+
return render_template('errors/500.html'), 500
20+
21+
22+
23+

0 commit comments

Comments
 (0)