美文网首页
Django搭建个人博客:完成修改文章功能

Django搭建个人博客:完成修改文章功能

作者: 杜赛_dusai | 来源:发表于2018-10-20 22:34 被阅读0次

    目前为止我们已经完成了文章的新建、删除以及查看,还剩最后一项,即对已经完成的文章进行修改。

    实际上修改文章与新建文章有点类似,不同的地方有两点:

    • 修改是在原有文章的基础上,因此需要传递 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页面寻找出错的线索,求助网络帮忙解决吧。

    总结

    至此我们就实现了一篇文章的增、删、改、查四个基础功能,也算小有成就。

    当然还有很多进阶的功能可以去做,不过我们在这里先休息休息,来罐快乐水庆祝一下。

    下一章开始解决更加燃眉之急的内容:用户管理。

    转载请告知作者并注明出处。

    相关文章

      网友评论

          本文标题:Django搭建个人博客:完成修改文章功能

          本文链接:https://www.haomeiwen.com/subject/ivkvzftx.html