目前为止我们已经完成了文章的新建, 删除以及查看, 还剩最后一项, 即对已经完成的文章进行修改.
实际上修改文章与新建文章有点类似, 不同的地方有两点:
修改是在原有文章的基础上, 因此需要传递 id 指明具体需要修改的文章
加载页面时需要将旧的内容作为默认值填写到表单中, 因此需要将文章对象传递到 html 中
按照这个思路, 接下来先写视图函数.
视图函数
在 ariticle/views.py 中增加修改文章的视图函数 article_update():
- article/views.py
- ...
- # 更新文章
- def article_update(request, id):
- """
- 更新文章的视图函数
- 通过 POST 方法提交表单, 更新 titile,body 字段
- GET 方法进入初始表单页面
- id: 文章的 id
- """
- # 获取需要修改的具体文章对象
- article = ArticlePost.objects.get(id=id)
- # 判断用户是否为 POST 提交表单数据
- if request.method == "POST":
- # 将提交的数据赋值到表单实例中
- article_post_form = ArticlePostForm(data=request.POST)
- # 判断提交的数据是否满足模型的要求
- if article_post_form.is_valid():
- # 保存新写入的 title,body 数据并保存
- article.title = request.POST['title']
- article.body = request.POST['body']
- article.save()
- # 完成后返回到修改后的文章中. 需传入文章的 id 值
- return redirect("article:article_detail", id=id)
- # 如果数据不合法, 返回错误信息
- else:
- return HttpResponse("表单内容有误, 请重新填写.")
- # 如果用户 GET 请求获取数据
- else:
- # 创建表单类实例
- article_post_form = ArticlePostForm()
- # 赋值上下文, 将 article 文章对象也传递进去, 以便提取旧的内容
- context = { 'article': article, 'article_post_form': article_post_form }
- # 将响应返回到模板中
- return render(request, 'article/update.html', context)
更新的视图与创建文章非常相似, 但又有点小区别:
文章的 id 作为参数传递进来了
用户 POST 提交表单时没有创建新的文章, 而是在之前的文章中修改
redirect 函数没有返回文章列表, 而是返回到修改后的文章页面去了, 因此需要同时把文章的 id 也打包传递进去, 这是 url 所规定的
GET 获取页面时将 article 对象也传递到模板中去, 以便后续的调用
编写模板
模板文件就与创建文章的更像了, 不过我们这里还是重新写一遍.
新建 templates/article/update.HTML 并写入:
- templates/article/update.HTML
- {
- % extends "base.html" %
- } {
- % load staticfiles %
- }
{% block title %} 更新文章 {% endblock title %}
- {% block content %}
- <div class="container">
- <div class="row">
- <div class="col-12">
- <br>
- <form method="post" action=".">
- {% csrf_token %}
- <div class="form-group">
- <label for="title"> 文章标题 </label>
- <!-- 在 value 属性中指定文本框的初始值为旧的内容, 即 article 对象中的 title 字段 -->
- <input type="text" class="form-control" id="title" name="title" value="{{ article.title }}">
- </div>
- <div class="form-group">
- <label for="body"> 文章正文 </label>
- <!-- 文本域不需要 value 属性, 直接在标签体中嵌入数据即可 -->
- <textarea type="text" class="form-control" id="body" name="body" rows="12">{{ article.body }}</textarea>
- </div>
- <button type="submit" class="btn btn-primary"> 完成 </button>
- </form>
- </div>
- </div>
- </div>
- {% endblock content %}
在模板中, 分别将文章旧的标题和正文作为初始值, 传递了进去, 其他就与新建文章的模板完全没区别了.
有读者可能就会问了, 既然这两个函数, 模板都很相似,** 能不能合并成一个函数, 模板呢?** 当然是可以的, 合并相同功能的函数可以让代码更加简洁漂亮, 也便于后期的维护. 有兴趣的读者可以自己尝试一下.
URL 和入口
接下来的套路都懂的, 配置路由 article/urls.py:
- article/urls.py
- ...
- urlpatterns = [
- ...
- # 更新文章
- path('article-update/<int:id>/', views.article_update, name='article_update'),
- ]
在文章详情页面 tempaltes/article/detail.HTML 中添加修改文章的入口:
- tempaltes/article/detail.HTML
- ...
- <div class="col-12 alert alert-success"> 作者:{
- {
- article.author
- }
- }
. <a href="#" onclick="confirm_delete()"> 删除文章 </a>
. <a href="{% url"article:article_update"article.id %}"> 编辑文章 </a>
</div>
启动服务器, 可以看到修改文章的功能就实现了. 同样的, 如有故障也不要着急, 在 Debug 页面寻找出错的线索, 求助网络帮忙解决吧.
总结
至此我们就实现了一篇文章的增, 删, 改, 查四个基础功能, 也算小有成就.
当然还有很多进阶的功能可以去做, 不过我们在这里先休息休息, 来罐快乐水庆祝一下.
下一章开始解决更加燃眉之急的内容: 用户管理.
有疑问请在杜赛的个人网站 http://www.dusaiphoto.com 留言, 我会尽快回复.
或 Email 私信我: dusaiphoto@foxmail.com
项目完整代码: Django_blog_tutorial https://github.com/stacklens/django_blog_tutorial
来源: https://juejin.im/post/5bcb3d266fb9a05d3a4b6dac