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

目前爲止我們已經完成了文章的新建、刪除以及查看,還剩最後一項,即對已經完成的文章進行修改。

實際上修改文章與新建文章有點類似,不同的地方有兩點:

  • 修改是在原有文章的基礎上,因此需要傳遞 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頁面尋找出錯的線索,求助網絡幫忙解決吧。

總結

至此我們就實現了一篇文章的增、刪、改、查四個基礎功能,也算小有成就。

當然還有很多進階的功能可以去做,不過我們在這裏先休息休息,來罐快樂水慶祝一下。

下一章開始解決更加燃眉之急的內容:用戶管理。

轉載請告知作者並註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章