今天我们要来处理 dashboard 的部分,但仅限於贴文的,留言的要留到明天。
第一个要来看的是 dashboard,有些东西还没有写好 (像是删除之类的),会等写完这边再回去看。
一样,先来看看资料库方面的程序码。
def get_posts(user_id=None, start=None, end=None):
query = Posts.query
if user_id:
query = query.filter_by(author_id=user_id)
if start:
query = query.filter(Posts.time > start)
if end:
query = query.filter(Posts.time < end)
posts = [post.id for post in query.all()]
posts = list(map(render_post, posts))
return posts
这边我们让他接收一些过滤器去做筛选,然後把过滤过的贴文都抓出来,再丢进昨天写的 render_post
让他转成 dict。这边值得注意一下的是我们有 filter
也有 filter_by
,後者是我们熟悉的,而前者也一样是筛选器,只是它里面放的是判断式,所以如果之前的 filter_by
想要改成 filter
,那就要把 =
改成 ==
。
接下来进入 HTML,这次会比前面复杂一些,因为要加上显示贴文。
dashboard.html
{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
<form action="/dashboard" method="post">
{{ form.csrf_token }}
{{ form.start }}
{{ form.end }}
{{ form.submit }}
</form>
<div>
{% for post in posts %}
<div>
{{ post['author_id'] }}
<a href="/post/{{ post['id'] }}">{{ post['title'] }}</a>
{{ post['description'] }}
{{ post['time'] }}
<a href="/post/edit/{{ post['id'] }}">edit</a>
<a href="/post/delete/{{ post['id'] }}">delete</a>
</div>
{% endfor %}
</div>
{% endblock %}
最上面我们一样放了表单,是 filter
那个。然後在下面我们用到了 posts
,这是刚刚 get_posts
弄出来的,所以会是一个有很多贴文 dict 的 list,我们就一个一个抓出来,然後把它的资讯呈现出来。我们放了很多连结,现在只有编辑的部分昨天实作了,剩下的我们会等等完成。
最後来到路径本身,他也相对复杂。
@user_bp.route("/dashboard", methods=["GET", "POST"])
@login_required
def dashboard_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")
form = DashboardFilterForm(**filter_args)
if request.method == "GET":
posts = get_posts(user_id=None, **filter_args)
return render_template("dashboard.html", posts=posts, form=form)
if request.method == "POST":
response = make_response(redirect(url_for("user.dashboard_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")))
response.delete_cookie("start")
response.delete_cookie("end")
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
在判断 request.method
前,我们有一小串跟其他路径不一样的程序码,它是用来取出 cookie 的,因为我们会把使用者指定的 filter 存在 cookie 里面。以现在的状况来看这基本上是多余的,直接把过滤过的贴文送出去就好,但如果未来我们加入分页的功能,那就没有这麽好处理了,所以我们在这边选择用 cookie。这个从 cookie 抓出来的 dict 除了要给 get_posts
用之外,也要给 DashboardFilterForm
当作预设值,这样使用者就可以看到他设定的过滤器是什麽。後面的部分基本上就是处理 cookie,要把表单送过来的东西都转成 cookie。
这里会有一个小问题发生在处理日期结束的地方,假设我们说结束时间是 2021-01-02
,但事实上在资料库时间比大小的时候 2021-01-02
的资料不会跑出来,因为我们说的结束时间会被当成 2021-01-02 00:00:00
,这样就会让那些 2021-01-02
的资料被过滤掉,平常我自己会直接手动加一天,不过为了简洁一点,我这边就跳过这个部分。
接着我们来看看删除文章也一样从资料库的部分看起。
def delete_post(user_id, post_id):
post = Posts.query.filter_by(id=post_id).first()
if post.author_id == user_id:
db.session.delete(post)
db.session.commit()
return True
else:
return False
他有 user_id
、post_id
两个参数,会需要前者是因为我们不能让莫名其妙的人乱删别人的文章,所以必须确定要删除这篇文章的人的确是其所有者。我们删除的方法是用 db.session.delete()
,里面的参数是物件,而不是 query
,所以要记得 .first()
。
而他不会有 HTML,来看路径就知道为什麽了。
@user_bp.route("/post/delete/<int:post_id>", methods=["GET"])
@login_required
def delete_post_page(post_id):
if delete_post(current_user.id, post_id):
flash("OK.")
else:
flash("Failed.")
return redirect(url_for("user.dashboard"))
他的路径非常简单,基本上就是把 post_id
转送给刚刚的 delete_post
,最後再重新导向到 dashboard。
GitHub:https://github.com/dannypc1628/Angular-Tou...
前言 我们目前把laravel的服务都写得差不多了 後来发现没有实际测试过订单建立 这边我们来把订单...
之前为方便快速了解我们程序完整的功能, 所以把所有的资料都放在Controller里面。 今天这篇我...
在前面章节已介绍如何让Arduino Nano 33 BLE Sense(以下简称BLE Sense...
大家好,我是韦恩,今天是铁人赛的第三十一天,今天我们来练习一下在web里怎麽提供editor区块编辑...