摘要:本教程內容已過時,更新版教程請訪問博客開發入門教程。我們的評論表單放在中,評論成功后返回到原始提交頁面。學習小組簡介學習小組是一個促進新手互相學習互相幫助的組織。
本教程內容已過時,更新版教程請訪問: django 博客開發入門教程。
通過前四周的時間我們開發了一個簡單的個人 Blog,前幾期教程地址:
第一周:Django 學習小組:博客開發實戰第一周教程 —— 編寫博客的 Model 和首頁面
第二周:Django 學習小組:博客開發實戰第二周教程 —— 博客詳情頁面和分類頁面
第三周:Django 學習小組:博客開發實戰第三周教程 —— 文章列表分頁和代碼語法高亮
番外:Django 學習小組:基于類的通用視圖詳解(一)
第四周:Django 學習小組:博客開發實戰第四周——標簽云與文章歸檔
本周我們將實現 blog 文章的評論功能。
實現思路提示:在閱讀教程的過程中,如有任何問題請訪問我們項目的 GithHub 或評論留言以獲取幫助,本教程的相關代碼已全部上傳在 Github。如果你對我們的教程或者項目有任何改進建議,請您隨時告知我們。更多交流請加入我們的郵件列表?django_study@groups.163.com 和關注我們在 GithHub 上的項目。
本文首發于編程派微信公眾號:編程派(微信號:codingpy)是一個專注Python編程的公眾號,每天更新有關Python的國外教程和優質書籍等精選干貨,歡迎關注。
首先需要為評論(Comment)設計一個數據庫表,并編寫相應的 Model,將評論與文章關聯,再編寫發表評論的視圖,設置相應的 url 即可。
評論的 Model 設計blog/models.py class BlogComment(models.Model): user_name = models.CharField("評論者名字", max_length=100) user_email = models.EmailField("評論者郵箱", max_length=255) body = models.TextField("評論內容") created_time = models.DateTimeField("評論發表時間", auto_now_add=True) article = models.ForeignKey("Article", verbose_name="評論所屬文章", on_delete=models.CASCADE) def __str__(self): return self.body[:20]
參照大部分博客評論的樣式,我們的 BlogComment Model 包含這些字段:
user_name:用戶在評論前先要填寫他們想使用的昵稱
user_email:用戶在評論前先要填寫他們想使用的郵箱
body:用戶提交的評論內容
created_time:評論提交時間
article:評論關聯的文章,因為一個評論只能關聯某一篇文章,而一篇文章下可能有多個評論,因此是一對多的關系,使用 ForeignKey
評論的表單表單用來給服務器后臺提交用戶填寫的數據,例如平時我們看到的填寫登錄、注冊信息的頁面就是一個登錄、注冊表單,用戶填寫表單信息后,點擊提交按鈕,表單中填寫的內容就會打包發送給服務器后臺。我們需要為用戶填寫評論設置一個表單,django 的 form 模塊為我們提供了自動生成表單的功能,如果對表單不熟悉請參閱:官方文檔:表單概述 ,以了解基本的表單使用方法(如果你對表單感覺很陌生的話)。下面我們使用 Django 的 ModelForm ( django ModelForm 介紹 )類為我們自動生成表單。首先在 blog 目錄下新建一個 forms.py (和 models.py 同一目錄)文件用來存放 form 的代碼:
blog/forms.py from django import forms from .models import Article, BlogComment class BlogCommentForm(forms.ModelForm): class Meta: """指定一些 Meta 選項以改變 form 被渲染后的樣式""" model = BlogComment # form 關聯的 Model fields = ["user_name", "user_email", "body"] # fields 表示需要渲染的字段,這里需要渲染user_name、user_email、body # 這樣渲染后表單會有三個文本輸入框,分別是輸入user_name、user_email、body的輸入框 widgets = { # 為各個需要渲染的字段指定渲染成什么html組件,主要是為了添加css樣式。 # 例如 user_name 渲染后的html組件如下: # "user_name": forms.TextInput(attrs={ "class": "form-control", "placeholder": "請輸入昵稱", "aria-describedby": "sizing-addon1", }), "user_email": forms.TextInput(attrs={ "class": "form-control", "placeholder": "請輸入郵箱", "aria-describedby": "sizing-addon1", }), "body": forms.Textarea(attrs={"placeholder": "我來評兩句~"}), }視圖函數
這里我們一如既往堅持使用基于類的通用視圖,由于涉及到評論表單的提交處理,因此我們使用 FormView。這里對 FormView 的使用稍作講解。
在 Django 的基于函數的視圖中,涉及表單的處理的視圖其邏輯一般是這樣的:
def post_comment(request): if request.method =="POST": form = BlogCommentForm(request.POST) if form.is_valid(): ... else: ... else: ...
即,首先判斷用戶是否通過表單 POST 了數據過來,如果是,則根據 POST 過來的數據構建一個表單,如果數據驗證合法(form.is_valid),則創建評論,否則返回表單提交頁。如果沒有 POST 數據,則做其他相應的事情。FormView 把這些邏輯做了整合,無需寫那么多 if else 語句:
blog/views.py from django.views.generic.edit import FormView ... class CommentPostView(FormView): form_class = BlogCommentForm # 指定使用的是哪個form template_name = "blog/detail.html" # 指定評論提交成功后跳轉渲染的模板文件。 # 我們的評論表單放在detail.html中,評論成功后返回到原始提交頁面。 def form_valid(self, form): """提交的數據驗證合法后的邏輯""" # 首先根據 url 傳入的參數(在 self.kwargs 中)獲取到被評論的文章 target_article = get_object_or_404(Article, pk=self.kwargs["article_id"]) # 調用ModelForm的save方法保存評論,設置commit=False則先不保存到數據庫, # 而是返回生成的comment實例,直到真正調用save方法時才保存到數據庫。 comment = form.save(commit=False) # 把評論和文章關聯 comment.article = target_article comment.save() # 評論生成成功,重定向到被評論的文章頁面,get_absolute_url 請看下面的講解。 self.success_url = target_article.get_absolute_url() return HttpResponseRedirect(self.success_url) def form_invalid(self, form): """提交的數據驗證不合法后的邏輯""" target_article = get_object_or_404(Article, pk=self.kwargs["article_id"]) # 不保存評論,回到原來提交評論的文章詳情頁面 return render(self.request, "blog/detail.html", { "form": form, "article": target_article, "comment_list": target_article.blogcomment_set.all(), })
為了方便地重定向回原來提交評論的文章詳情頁面,我們為文章(Article)的模型新增一個方法:get_absolute_url,調用該方法將得到該 Article 對應的 url,例如這是文章 1 的 url:http://localhost:8000/article/1,則調用后返回 /article/1,這樣調用 HttpResponseRedirect 后將返回該 url 下的文章詳情頁。
blog/models.py from django.core.urlresolvers import reverse class Article(models.Model): STATUS_CHOICES = ( ("d", "Draft"), ("p", "Published"), ) ... class Meta: ordering = ["-last_modified_time"] # 新增 get_absolute_url 方法 def get_absolute_url(self): # 這里 reverse 解析 blog:detail 視圖函數對應的 url return reverse("blog:detail", kwargs={"article_id": self.pk})
同時為了在詳情頁渲染一個評論表單,稍微修改一下 ArticleDetailView 的視圖函數,把評論表單 form 插入模板上下文中:
blog/views.py class ArticleDetailView(DetailView): model = Article template_name = "blog/detail.html" context_object_name = "article" pk_url_kwarg = "article_id" def get_object(self, queryset=None): obj = super(ArticleDetailView, self).get_object() obj.body = markdown2.markdown(obj.body, extras=["fenced-code-blocks"], ) return obj # 新增 form 到 context def get_context_data(self, **kwargs): kwargs["comment_list"] = self.object.blogcomment_set.all() kwargs["form"] = BlogCommentForm() return super(ArticleDetailView, self).get_context_data(**kwargs)URL 設置
urlpatterns = [ url(r"^$", views.IndexView.as_view(), name="index"), ... # 設置評論視圖對應的 url url(r"^article/(?P設置模板文件d+)/comment/$", views.CommentPostView.as_view(), name="comment"), ]
新增了一個 comment.html 文件以渲染評論表單和評論列表,并且修改了 detail.html 文件以在文章詳情頁顯示評論表單和評論列表,修改了blog/tatic 下的 style.css 為評論添加樣式,由于代碼比較多,就不貼出來了,主要是 html 和 css 的前端相關代碼,請到 GitHub 倉庫 更新相關的模板和靜態資源文件。
至此,整個評論功能的框架做好了,顯示效果如下:
當然這只是一個評論的框架,很多細節有待處理和完善,但無論如何,用戶可以為我們的文章發表評論意見了。
Django學習小組簡介django學習小組是一個促進 django 新手互相學習、互相幫助的組織。
小組在一邊學習 django 的同時將一起完成幾個項目,包括:
一個簡單的 django 博客,用于發布小組每周的學習和開發文檔;
django中國社區,為國內的 django 開發者們提供一個長期維護的 django 社區;
上面所說的這個社區類似于 segmentfault 和 stackoverflow ,但更加專注(只專注于 django 開發的問題)。
更多的信息請關注我們的?github 組織,本教程項目的相關源代碼也已上傳到 github 上。
同時,你也可以加入我們的郵件列表?django_study@groups.163.com?,隨時關注我們的動態。我們會將每周的詳細開發文檔和代碼通過郵件列表發出。
如有任何建議,歡迎提 Issue,歡迎 fork,pr,當然也別忘了 star 哦!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38031.html
摘要:本教程內容已過時,更新版教程請訪問博客開發入門教程。我們的評論表單放在中,評論成功后返回到原始提交頁面。學習小組簡介學習小組是一個促進新手互相學習互相幫助的組織。 本教程內容已過時,更新版教程請訪問: django 博客開發入門教程。 通過前四周的時間我們開發了一個簡單的個人 Blog,前幾期教程地址: 第一周:Django 學習小組:博客開發實戰第一周教程 —— 編寫博客的 Mode...
摘要:本教程內容已過時,更新版教程請訪問博客開發入門教程。表示降序排列,默認是升序排列。學習小組簡介學習小組是一個促進新手互相學習互相幫助的組織。我們會將每周的詳細開發文檔和代碼通過郵件列表發出。 本教程內容已過時,更新版教程請訪問: django 博客開發入門教程。 通過前四周的時間我們開發了一個簡單的個人 Blog,教程地址: 第一周:Django 學習小組:博客開發實戰第一周教程 ——...
摘要:本節接上周的文檔學習小組博客開發實戰第一周教程編寫博客的首頁面,我們繼續給博客添加功能,以及改善前面不合理的部分。返回該視圖要顯示的對象。目前小組正在完成第一個項目,本文即是該項目第二周的相關文檔。 本教程內容已過時,更新版教程請訪問: django 博客開發入門教程。 上周我們完成了博客的 Model 部分,以及 Blog 的首頁視圖 IndexView。 本節接上周的文檔 Djan...
摘要:本教程內容已過時,更新版教程請訪問博客開發入門教程。當分頁較多時,總是顯示當前頁及其前幾頁和后幾頁的頁碼教程中使用的是兩頁,其他頁碼用省略號代替。 本教程內容已過時,更新版教程請訪問: django 博客開發入門教程。 摘要:前兩期教程我們實現了博客的 Model 部分,以及 Blog 的首頁視圖 IndexView,詳情頁面 DetailView,以及分類頁面 CategoryVi...
摘要:本教程首先介紹兩個項目中遇到的通用視圖和。語句的作用是添加了到上下文中,還要把默認的一些上下文變量也返回給視圖函數,以便其后續處理。 通過三周的時間我們開發了一個簡單的個人 Blog,教程地址: 第一周:Django 學習小組:博客開發實戰第一周教程 —— 編寫博客的 Model 和首頁面 第二周:Django 學習小組:博客開發實戰第二周教程 —— 博客詳情頁面和分類頁面 第三周:D...
閱讀 3708·2021-10-18 13:34
閱讀 2396·2021-08-11 11:15
閱讀 1201·2019-08-30 15:44
閱讀 687·2019-08-26 10:32
閱讀 986·2019-08-26 10:13
閱讀 2065·2019-08-23 18:36
閱讀 1775·2019-08-23 18:35
閱讀 523·2019-08-23 17:10