今天要開始寫 admin_bp
,有蠻多部分跟之前很像。
先來看看 HTML 的部分。
admin_dashboard_posts.html
{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
<form action="/admin_dashboard/posts" method="post">
{{ form.csrf_token }}
{{ form.start }}
{{ form.end }}
{{ form.user_id }}
{{ form.submit }}
</form>
<div>
{% for post in posts %}
<div>
{{ post['author_id'] }}
<a href="/post/{{ post['id'] }}">{{ post['title'] }}</a>
{{ post['description'] }}
{{ post['time'] }}
<button>Delete</button>
</div>
{% endfor %}
</div>
{% endblock %}
基本上跟一般使用者的 dashboard 差不多,但 form
的部分新加入了一個 user_id
的欄位。在最後面有一個刪除的按鈕,它今天還不會登場。
接下來進入路徑的部分,也一樣跟使用者的 dashboard 類似,因為都有篩選器。
@admin_bp.route("/admin_dashboard/posts", methods=["GET", "POST"])
def admin_dashboard_posts_page():
filter_args = {}
if start := request.cookies.get("start"):
filter_args["start"] = datetime.datetime.strptime(start, "%Y-%m-%d")
if end := request.cookies.get("end"):
filter_args["end"] = datetime.datetime.strptime(end, "%Y-%m-%d")
if user_id := request.cookies.get("user_id"):
filter_args["user_id"] = user_id
form = AdminDashboardFilter(**filter_args)
if request.method == "GET":
posts = get_posts(**filter_args)
return render_template("admin_dashboard_posts.html", posts=posts, form=form)
if request.method == "POST":
response = make_response(redirect(url_for("admin.admin_dashboard_posts_page")))
if form.validate_on_submit():
cookies = []
if form.start.data:
cookies.append(("start", form.start.data.strftime("%Y-%m-%d")))
if form.end.data:
cookies.append(("end", form.end.data.strftime("%Y-%m-%d")))
if form.user_id.data:
cookies.append(("user_id", str(form.user_id.data)))
response.delete_cookie("start")
response.delete_cookie("end")
response.delete_cookie("user_id")
for cookie in cookies:
response.set_cookie(*cookie)
else:
for _, errors in form.errors.items():
for error in errors:
flash(error, category="alert")
return response
基本上就是直接從使用者 dashboard 抄過來的,只是多加一個 user_id
而已。但還是有一個小東西要注意一下,在拉出 user_id
的時候要把他轉成字串,不然會噴錯誤。
接著來到留言的 dashboard,跟剛剛也是很接近,但要先來加一個資料庫的函式。
def get_all_comments(user_id=None, start=None, end=None):
query = Comments.query
if user_id:
query = query.filter_by(user_id)
if start:
query = query.filter(Comments.time > start)
if end:
query = query.filter(Comments.time < end)
return [
{
"id": comment.id,
"author_id": comment.author_id,
"post_id": comment.post_id,
"content": comment.content,
}
for comment in query.all()
]
基本上就是把 get_posts
拿來這邊改一下而已。
接下來是他的 HTML。
admin_dashboard_comments.html
{% extends "base.html" %}
{% block title %}comments{% endblock %}
{% block content %}
<form action="/admin_dashboard/comments" method="post">
{{ form.csrf_token }}
{{ form.start }}
{{ form.end }}
{{ form.user_id }}
{{ form.submit }}
</form>
<div>
{% for comment in comments %}
{{ comment['author_id'] }}
{{ comment['post_id'] }}
{{ comment['content'] }}
{{ comment['time'] }}
<button>Delete</button>
{% endfor %}
</div>
{% endblock %}
表單也是一樣的,就是篩選器。跟剛剛一樣,他也有刪除的按鈕。
最後來到路徑的部分。
@admin_bp.route("/admin_dashboard/comments", methods=["GET"])
def admin_dashboard_comments_page():
filter_args = {}
if start := request.cookies.get("start"):
filter_args["start"] = datetime.datetime.strptime(start, "%Y-%m-%d")
if end := request.cookies.get("end"):
filter_args["end"] = datetime.datetime.strptime(end, "%Y-%m-%d")
if user_id := request.cookies.get("user_id"):
filter_args["user_id"] = user_id
form = AdminDashboardFilter(**filter_args)
if request.method == "GET":
comments = get_all_comments(**filter_args)
return render_template("admin_dashboard_comments.html", comments=comments, form=form)
if request.method == "POST":
response = make_response(redirect(url_for("admin.admin_dashboard_comments_page")))
if form.validate_on_submit():
cookies = []
if form.start.data:
cookies.append(("start", form.start.data.strftime("%Y-%m-%d")))
if form.end.data:
cookies.append(("end", form.end.data.strftime("%Y-%m-%d")))
if form.user_id.data:
cookies.append(("user_id", str(form.user_id.data)))
response.delete_cookie("start")
response.delete_cookie("end")
response.delete_cookie("user_id")
for cookie in cookies:
response.set_cookie(*cookie)
else:
for _, errors in form.errors.items():
for error in errors:
flash(error, category="alert")
return response
跟剛剛幾乎一模一樣,只是把貼文換成留言而已。
在今天的最後,我們要處理管理使用者的介面。一樣先從資料庫部分看起。
def get_all_users(user_id=None, username=None, start=None, end=None):
query = Users.query
if user_id:
query = query.filter_by(id=user_id)
if username:
query = query.filter_by(username=username)
if start:
query = query.filter(Users.register_time > start)
if end:
query = query.filter(Users.register_time < end)
return user_to_dict(query.all())
基本上都跟剛剛很接近,只是這裏我們用已經寫好的 user_to_dict
取代剛剛的 list comprehension。
接著是 HTML 的部分,基本上也蠻類似的。
manage_user.html
{% extends "base.html" %}
{% block title %}Manage User{% endblock %}
{% block content %}
<form action="/manage_user" method="post">
{{ form.csrf_token }}
{{ form.start }}
{{ form.end }}
{{ form.user_id }}
{{ form.username }}
{{ form.submit }}
</form>
<div>
{% for user in users %}
<div>
<span>{{ user['id'] }}</span>
<input type="text" value="{{ user['username'] }}">
<input type="email" value="{{ user['email'] }}">
<input type="checkbox" {% if user['is_admin'] %} checked {% endif %}>
<input type="text" value="{{ user['introduction'] }}">
<span>{{ user['register_time'] }}</span>
<button>Delete</button>
<button>Update</button>
</div>
{% endfor %}
</div>
{% endblock %}
稍微不一樣的是我們把單純的顯示出來變成了 input
,這樣管理員才可以直接修改,裡面沒有加上密碼的欄位,因為太煩了,而且也是可以想到的東西,就不在這邊做。還有一個不一樣的地方是 user['is_admin']
的部分,我們在那裏用了一個 if 來判斷他是不是管理員,如果是的話就把那個 checkbox 勾起來。
最後要看的是路徑本身,基本上就是跟前面兩個相同。
@admin_bp.route("/manage_user", methods=["GET", "POST"])
def manage_user_page():
filter_args = {}
if start := request.cookies.get("start"):
filter_args["start"] = datetime.datetime.strptime(start, "%Y-%m-%d")
if end := request.cookies.get("end"):
filter_args["end"] = datetime.datetime.strptime(end, "%Y-%m-%d")
if user_id := request.cookies.get("user_id"):
filter_args["user_id"] = user_id
if username := request.cookies.get("username"):
filter_args["username"] = username
form = UserFilterForm(**filter_args)
if request.method == "GET":
users = get_all_users(**filter_args)
return render_template("manage_user.html", users=users, form=form)
if request.method == "POST":
response = make_response(redirect(url_for("admin.manage_user_page")))
if form.validate_on_submit():
cookies = []
if form.start.data:
cookies.append(("start", form.start.data.strftime("%Y-%m-%d")))
if form.end.data:
cookies.append(("end", form.end.data.strftime("%Y-%m-%d")))
if form.user_id.data:
cookies.append(("user_id", str(form.user_id.data)))
if form.username.data:
cookies.append(("username", form.username.data))
response.delete_cookie("start")
response.delete_cookie("end")
response.delete_cookie("user_id")
response.delete_cookie("username")
for cookie in cookies:
response.set_cookie(*cookie)
else:
for _, errors in form.errors.items():
for error in errors:
flash(error, category="alert")
return response
要記得把 form
改掉,也要記得多一個欄位 username
。