我们今天还是没有离开 user_bp
,我们要来弄写文章的页面,也就是 markdown 上场的日子。
首先一样要先来处理一下资料库的部分,需要一个加入新贴文的函式。
def add_post(user_id, title, description, content):
post = Posts(user_id, title, description, content)
try:
db.session.add(post)
db.session.commit()
return True
except:
return False
之前都是使用 Users
这个物件,这次要换成用 Posts
了。他会需要传入一些贴文的基本资料,然後把他加入资料库,如果有错误的话就代表他标题重复了 (空值的部分已经让 Flask-WTF 处理掉了)。
接下来是 HTML 的部分,他有一些些跟一般表单不一样的地方。
write.html
{% extends "base.html" %}
{% block title %}Post{% endblock %}
{% block content %}
{{ pagedown.include_pagedown() }}
<form action="{{ route }}" method="post">
{{ form.csrf_token }}
{{ form.title }}
{{ form.description }}
{{ form.content }}
{{ form.submit }}
</form>
{% endblock %}
他有一个 {{ pagedown.include_pagedown() }}
,这是用来引入外部 JS 来及时显示 markdown 用的。要注意它是 pagedown
的东西,而不是 form
,而这个 pagedown
就是一开始在 create_app
里面初始化用的那个。接下来会看到有一个 route
变数,这样 render_template
的时候就可以传入表单的提交路径。
接下来就跟之前差不多了,比较可以看一下的是 form.content
,我们用的是最直接简单的方法,但也可以稍微调整他,有兴趣的话可以去他的GitHub repo 看看范例。
最後就要来看路径了,基本上跟之前的结构都一样。
views.py
@user_bp.route("/post/add", methods=["GET", "POST"])
@login_required
def add_post_page():
form = AddPostForm()
if request.method == "GET":
return render_template("write.html", form=form, route="/post/add")
if request.method == "POST":
if form.validate_on_submit():
title = form.title.data
description = form.description.data
content = form.content.data
if add_post(current_user.id, title, description, content):
flash("Add post.")
return redirect(url_for("user.dashboard_page"))
else:
flash("The title has been used.")
return redirect(url_for("user.add_post_page"))
else:
for _, errors in form.errors.items():
for error in errors:
flash(error, category="alert")
return redirect(url_for("user.add_post_page"))
差不多就是把栏位都抓出来,然後 add_post
,没问题就跳到 dashboard,有问题就继续待在这里。但是在 render_template
的时候,我们加入了一个 route
,就是刚刚 write.html
里面的,决定表单要送去哪。
写完文章就要来改文章,所以接下来我们来处理编辑文章的页面。一样,先来看看资料库。
def edit_post(post_id, title, description, content):
post = Posts.query.filter_by(id=post_id)
try:
data = {"title": title, "description": description, "content": content}
post.update(data)
db.session.commit()
return True
except:
return False
def render_post(post_id):
post = Posts.query.filter_by(id=post_id).first()
return {
"id": post.id,
"author_id": post.author_id,
"title": post.title,
"description": post.description,
"content": post.content,
"comments": [
{
"author_id": comment.author_id,
"content": comment.content,
}
for comment in post.comments
],
}
这里有 edit_post
和 render_post
两个函式,前者是用来编辑文章,也就是把现有的文章抓出来再修改内容,所以用 post_id
当参数;而後者是把文章转成 dict 送出来。
依照惯例,我们应该要来写 HTML,但这次不需要,因为我们可以直接拿刚刚的 write.html
来用。所以我们可以直接进入路径的部分,可想而知,也会跟刚刚十分类似。
@user_bp.route("/post/edit/<int:post_id>", methods=["GET", "POST"])
@login_required
def edit_post_page(post_id):
post_data = render_post(post_id)
form = AddPostForm(
title=post_data["title"],
description=post_data["description"],
content=post_data["content"],
)
if request.method == "GET":
return render_template("write.html", form=form, route=f"/post/edit/{post_id}")
if request.method == "POST":
if form.validate_on_submit():
title = form.title.data
description = form.description.data
content = form.content.data
if edit_post(post_id, title, description, content):
flash("Post edited.")
return redirect(url_for("user.dashboard_page"))
else:
flash("The title has been used.")
return redirect(url_for("user.edit_post_page"))
else:
for _, errors in form.errors.items():
for error in errors:
flash(error, category="alert")
return redirect(url_for("user.edit_post_page"))
这里有比较不同的部分是在最前面我们先用刚刚的 render_post
把贴文的资料送出来,然後在建立表单的时候就直接把资料传进去,就像昨天弄使用者设定页面一样。接下来就十分类似,传不同的 route
给 jinja 处理,後面就都一样了。这边的 url_for
多了一个 post_id
的参数,会有他是因为这个编辑文章的页面有一个 post_id
的变数,如果不指定的话,flask 会无所适从,然後就喷错误了。
Create dynamic URLs in Flask with url_for()
Flask-PageDown
文件 Physical Memory Model 翻译: SPARSEMEM ========= S...
[Day1]C# 鸡础观念- C#简介 [Day2]C# 鸡础观念- 与C#开发千里来相见 [Da...
DAY8 MongoDB 批次操作(bulk wirte) 与 Operators bulk wri...
今天的便当是无淀粉系列 主菜是鲜甜的肉束尾 其实我本人很害怕猪肉的腥味 但男友妈妈准备的食材都很好 ...
来看看昨天的问题吧!顺便订个顺序~ javac 这个工具哪里来的呢? static 代表什麽意思呢?...