成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Django 學(xué)習(xí)小組:博客開發(fā)實(shí)戰(zhàn)第五周教程 —— 實(shí)現(xiàn)評(píng)論功能

CoderStudy / 3514人閱讀

摘要:本教程內(nèi)容已過時(shí),更新版教程請(qǐng)?jiān)L問博客開發(fā)入門教程。我們的評(píng)論表單放在中,評(píng)論成功后返回到原始提交頁面。學(xué)習(xí)小組簡(jiǎn)介學(xué)習(xí)小組是一個(gè)促進(jìn)新手互相學(xué)習(xí)互相幫助的組織。

本教程內(nèi)容已過時(shí),更新版教程請(qǐng)?jiān)L問: django 博客開發(fā)入門教程

通過前四周的時(shí)間我們開發(fā)了一個(gè)簡(jiǎn)單的個(gè)人 Blog,前幾期教程地址:

第一周:Django 學(xué)習(xí)小組:博客開發(fā)實(shí)戰(zhàn)第一周教程 —— 編寫博客的 Model 和首頁面

第二周:Django 學(xué)習(xí)小組:博客開發(fā)實(shí)戰(zhàn)第二周教程 —— 博客詳情頁面和分類頁面

第三周:Django 學(xué)習(xí)小組:博客開發(fā)實(shí)戰(zhàn)第三周教程 —— 文章列表分頁和代碼語法高亮

番外:Django 學(xué)習(xí)小組:基于類的通用視圖詳解(一)

第四周:Django 學(xué)習(xí)小組:博客開發(fā)實(shí)戰(zhàn)第四周——標(biāo)簽云與文章歸檔

本周我們將實(shí)現(xiàn) blog 文章的評(píng)論功能。

提示:在閱讀教程的過程中,如有任何問題請(qǐng)?jiān)L問我們項(xiàng)目的 GithHub 或評(píng)論留言以獲取幫助,本教程的相關(guān)代碼已全部上傳在 Github。如果你對(duì)我們的教程或者項(xiàng)目有任何改進(jìn)建議,請(qǐng)您隨時(shí)告知我們。更多交流請(qǐng)加入我們的郵件列表[email protected] 和關(guān)注我們?cè)?GithHub 上的項(xiàng)目。

本文首發(fā)于編程派微信公眾號(hào):編程派(微信號(hào):codingpy)是一個(gè)專注Python編程的公眾號(hào),每天更新有關(guān)Python的國(guó)外教程和優(yōu)質(zhì)書籍等精選干貨,歡迎關(guān)注。

實(shí)現(xiàn)思路

首先需要為評(píng)論(Comment)設(shè)計(jì)一個(gè)數(shù)據(jù)庫(kù)表,并編寫相應(yīng)的 Model,將評(píng)論與文章關(guān)聯(lián),再編寫發(fā)表評(píng)論的視圖,設(shè)置相應(yīng)的 url 即可。

評(píng)論的 Model 設(shè)計(jì)
blog/models.py

class BlogComment(models.Model):
    user_name = models.CharField("評(píng)論者名字", max_length=100)
    user_email = models.EmailField("評(píng)論者郵箱", max_length=255)
    body = models.TextField("評(píng)論內(nèi)容")
    created_time = models.DateTimeField("評(píng)論發(fā)表時(shí)間", auto_now_add=True)
    article = models.ForeignKey("Article", verbose_name="評(píng)論所屬文章", on_delete=models.CASCADE)

    def __str__(self):
        return self.body[:20]

參照大部分博客評(píng)論的樣式,我們的 BlogComment Model 包含這些字段:

user_name:用戶在評(píng)論前先要填寫他們想使用的昵稱

user_email:用戶在評(píng)論前先要填寫他們想使用的郵箱

body:用戶提交的評(píng)論內(nèi)容

created_time:評(píng)論提交時(shí)間

article:評(píng)論關(guān)聯(lián)的文章,因?yàn)橐粋€(gè)評(píng)論只能關(guān)聯(lián)某一篇文章,而一篇文章下可能有多個(gè)評(píng)論,因此是一對(duì)多的關(guān)系,使用 ForeignKey

評(píng)論的表單

表單用來給服務(wù)器后臺(tái)提交用戶填寫的數(shù)據(jù),例如平時(shí)我們看到的填寫登錄、注冊(cè)信息的頁面就是一個(gè)登錄、注冊(cè)表單,用戶填寫表單信息后,點(diǎn)擊提交按鈕,表單中填寫的內(nèi)容就會(huì)打包發(fā)送給服務(wù)器后臺(tái)。我們需要為用戶填寫評(píng)論設(shè)置一個(gè)表單,django 的 form 模塊為我們提供了自動(dòng)生成表單的功能,如果對(duì)表單不熟悉請(qǐng)參閱:官方文檔:表單概述 ,以了解基本的表單使用方法(如果你對(duì)表單感覺很陌生的話)。下面我們使用 Django 的 ModelForm ( django ModelForm 介紹 )類為我們自動(dòng)生成表單。首先在 blog 目錄下新建一個(gè) forms.py (和 models.py 同一目錄)文件用來存放 form 的代碼:

blog/forms.py

from django import forms
from .models import Article, BlogComment


class BlogCommentForm(forms.ModelForm):
    class Meta:
        """指定一些 Meta 選項(xiàng)以改變 form 被渲染后的樣式"""
        model = BlogComment # form 關(guān)聯(lián)的 Model
        
        fields = ["user_name", "user_email", "body"]
        # fields 表示需要渲染的字段,這里需要渲染user_name、user_email、body
        # 這樣渲染后表單會(huì)有三個(gè)文本輸入框,分別是輸入user_name、user_email、body的輸入框
        
        widgets = {
            # 為各個(gè)需要渲染的字段指定渲染成什么html組件,主要是為了添加css樣式。
            # 例如 user_name 渲染后的html組件如下:
            # 
            
            "user_name": forms.TextInput(attrs={
                "class": "form-control",
                "placeholder": "請(qǐng)輸入昵稱",
                "aria-describedby": "sizing-addon1",
            }),
            "user_email": forms.TextInput(attrs={
                "class": "form-control",
                "placeholder": "請(qǐng)輸入郵箱",
                "aria-describedby": "sizing-addon1",
            }),
            "body": forms.Textarea(attrs={"placeholder": "我來評(píng)兩句~"}),
        }
視圖函數(shù)

這里我們一如既往堅(jiān)持使用基于類的通用視圖,由于涉及到評(píng)論表單的提交處理,因此我們使用 FormView。這里對(duì) FormView 的使用稍作講解。

在 Django 的基于函數(shù)的視圖中,涉及表單的處理的視圖其邏輯一般是這樣的:

def post_comment(request):
    if request.method =="POST":
        form = BlogCommentForm(request.POST)
        if form.is_valid():
            ...
        else:
            ...
     else:
        ...

即,首先判斷用戶是否通過表單 POST 了數(shù)據(jù)過來,如果是,則根據(jù) POST 過來的數(shù)據(jù)構(gòu)建一個(gè)表單,如果數(shù)據(jù)驗(yàn)證合法(form.is_valid),則創(chuàng)建評(píng)論,否則返回表單提交頁。如果沒有 POST 數(shù)據(jù),則做其他相應(yīng)的事情。FormView 把這些邏輯做了整合,無需寫那么多 if else 語句:

blog/views.py

from django.views.generic.edit import FormView

...

class CommentPostView(FormView):
    form_class = BlogCommentForm # 指定使用的是哪個(gè)form
    template_name = "blog/detail.html" 
    # 指定評(píng)論提交成功后跳轉(zhuǎn)渲染的模板文件。
    # 我們的評(píng)論表單放在detail.html中,評(píng)論成功后返回到原始提交頁面。

    def form_valid(self, form):
        """提交的數(shù)據(jù)驗(yàn)證合法后的邏輯"""
        # 首先根據(jù) url 傳入的參數(shù)(在 self.kwargs 中)獲取到被評(píng)論的文章
        target_article = get_object_or_404(Article, pk=self.kwargs["article_id"])
        
        # 調(diào)用ModelForm的save方法保存評(píng)論,設(shè)置commit=False則先不保存到數(shù)據(jù)庫(kù),
        # 而是返回生成的comment實(shí)例,直到真正調(diào)用save方法時(shí)才保存到數(shù)據(jù)庫(kù)。
        comment = form.save(commit=False)
        
        # 把評(píng)論和文章關(guān)聯(lián)
        comment.article = target_article
        comment.save()
        
        # 評(píng)論生成成功,重定向到被評(píng)論的文章頁面,get_absolute_url 請(qǐng)看下面的講解。
        self.success_url = target_article.get_absolute_url()
        return HttpResponseRedirect(self.success_url)

    def form_invalid(self, form):
        """提交的數(shù)據(jù)驗(yàn)證不合法后的邏輯"""
        target_article = get_object_or_404(Article, pk=self.kwargs["article_id"])
        
        # 不保存評(píng)論,回到原來提交評(píng)論的文章詳情頁面
        return render(self.request, "blog/detail.html", {
            "form": form,
            "article": target_article,
            "comment_list": target_article.blogcomment_set.all(),
        })

為了方便地重定向回原來提交評(píng)論的文章詳情頁面,我們?yōu)槲恼拢ˋrticle)的模型新增一個(gè)方法:get_absolute_url,調(diào)用該方法將得到該 Article 對(duì)應(yīng)的 url,例如這是文章 1 的 url:http://localhost:8000/article/1,則調(diào)用后返回 /article/1,這樣調(diào)用 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 視圖函數(shù)對(duì)應(yīng)的 url
        return reverse("blog:detail", kwargs={"article_id": self.pk})

同時(shí)為了在詳情頁渲染一個(gè)評(píng)論表單,稍微修改一下 ArticleDetailView 的視圖函數(shù),把評(píng)論表單 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 設(shè)置
urlpatterns = [
    url(r"^$", views.IndexView.as_view(), name="index"),
    ...
    # 設(shè)置評(píng)論視圖對(duì)應(yīng)的 url
    url(r"^article/(?Pd+)/comment/$", views.CommentPostView.as_view(), name="comment"),
]
設(shè)置模板文件

新增了一個(gè) comment.html 文件以渲染評(píng)論表單和評(píng)論列表,并且修改了 detail.html 文件以在文章詳情頁顯示評(píng)論表單和評(píng)論列表,修改了blog/tatic 下的 style.css 為評(píng)論添加樣式,由于代碼比較多,就不貼出來了,主要是 html 和 css 的前端相關(guān)代碼,請(qǐng)到 GitHub 倉(cāng)庫(kù) 更新相關(guān)的模板和靜態(tài)資源文件。

至此,整個(gè)評(píng)論功能的框架做好了,顯示效果如下:

當(dāng)然這只是一個(gè)評(píng)論的框架,很多細(xì)節(jié)有待處理和完善,但無論如何,用戶可以為我們的文章發(fā)表評(píng)論意見了。

Django學(xué)習(xí)小組簡(jiǎn)介

django學(xué)習(xí)小組是一個(gè)促進(jìn) django 新手互相學(xué)習(xí)、互相幫助的組織。

小組在一邊學(xué)習(xí) django 的同時(shí)將一起完成幾個(gè)項(xiàng)目,包括:

一個(gè)簡(jiǎn)單的 django 博客,用于發(fā)布小組每周的學(xué)習(xí)和開發(fā)文檔;

django中國(guó)社區(qū),為國(guó)內(nèi)的 django 開發(fā)者們提供一個(gè)長(zhǎng)期維護(hù)的 django 社區(qū);

上面所說的這個(gè)社區(qū)類似于 segmentfault 和 stackoverflow ,但更加專注(只專注于 django 開發(fā)的問題)。

更多的信息請(qǐng)關(guān)注我們的?github 組織,本教程項(xiàng)目的相關(guān)源代碼也已上傳到 github 上。

同時(shí),你也可以加入我們的郵件列表[email protected]?,隨時(shí)關(guān)注我們的動(dòng)態(tài)。我們會(huì)將每周的詳細(xì)開發(fā)文檔和代碼通過郵件列表發(fā)出。

如有任何建議,歡迎提 Issue,歡迎 fork,pr,當(dāng)然也別忘了 star 哦!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/49891.html

相關(guān)文章

  • Django 學(xué)習(xí)小組博客開發(fā)實(shí)戰(zhàn)五周教程 —— 實(shí)現(xiàn)評(píng)論功能

    摘要:本教程內(nèi)容已過時(shí),更新版教程請(qǐng)?jiān)L問博客開發(fā)入門教程。我們的評(píng)論表單放在中,評(píng)論成功后返回到原始提交頁面。學(xué)習(xí)小組簡(jiǎn)介學(xué)習(xí)小組是一個(gè)促進(jìn)新手互相學(xué)習(xí)互相幫助的組織。 本教程內(nèi)容已過時(shí),更新版教程請(qǐng)?jiān)L問: django 博客開發(fā)入門教程。 通過前四周的時(shí)間我們開發(fā)了一個(gè)簡(jiǎn)單的個(gè)人 Blog,前幾期教程地址: 第一周:Django 學(xué)習(xí)小組:博客開發(fā)實(shí)戰(zhàn)第一周教程 —— 編寫博客的 Mode...

    kumfo 評(píng)論0 收藏0
  • Django 學(xué)習(xí)小組博客開發(fā)實(shí)戰(zhàn)第四周——標(biāo)簽云與文章歸檔

    摘要:本教程內(nèi)容已過時(shí),更新版教程請(qǐng)?jiān)L問博客開發(fā)入門教程。表示降序排列,默認(rèn)是升序排列。學(xué)習(xí)小組簡(jiǎn)介學(xué)習(xí)小組是一個(gè)促進(jìn)新手互相學(xué)習(xí)互相幫助的組織。我們會(huì)將每周的詳細(xì)開發(fā)文檔和代碼通過郵件列表發(fā)出。 本教程內(nèi)容已過時(shí),更新版教程請(qǐng)?jiān)L問: django 博客開發(fā)入門教程。 通過前四周的時(shí)間我們開發(fā)了一個(gè)簡(jiǎn)單的個(gè)人 Blog,教程地址: 第一周:Django 學(xué)習(xí)小組:博客開發(fā)實(shí)戰(zhàn)第一周教程 ——...

    RichardXG 評(píng)論0 收藏0
  • Django 學(xué)習(xí)小組博客開發(fā)實(shí)戰(zhàn)第二周教程 —— 實(shí)現(xiàn)博客詳情頁面和分類頁面

    摘要:本節(jié)接上周的文檔學(xué)習(xí)小組博客開發(fā)實(shí)戰(zhàn)第一周教程編寫博客的首頁面,我們繼續(xù)給博客添加功能,以及改善前面不合理的部分。返回該視圖要顯示的對(duì)象。目前小組正在完成第一個(gè)項(xiàng)目,本文即是該項(xiàng)目第二周的相關(guān)文檔。 本教程內(nèi)容已過時(shí),更新版教程請(qǐng)?jiān)L問: django 博客開發(fā)入門教程。 上周我們完成了博客的 Model 部分,以及 Blog 的首頁視圖 IndexView。 本節(jié)接上周的文檔 Djan...

    ingood 評(píng)論0 收藏0
  • Django 學(xué)習(xí)小組博客開發(fā)實(shí)戰(zhàn)第三周教程——文章列表分頁和代碼語法高亮

    摘要:本教程內(nèi)容已過時(shí),更新版教程請(qǐng)?jiān)L問博客開發(fā)入門教程。當(dāng)分頁較多時(shí),總是顯示當(dāng)前頁及其前幾頁和后幾頁的頁碼教程中使用的是兩頁,其他頁碼用省略號(hào)代替。 本教程內(nèi)容已過時(shí),更新版教程請(qǐng)?jiān)L問: django 博客開發(fā)入門教程。 摘要:前兩期教程我們實(shí)現(xiàn)了博客的 Model 部分,以及 Blog 的首頁視圖 IndexView,詳情頁面 DetailView,以及分類頁面 CategoryVi...

    Luosunce 評(píng)論0 收藏0
  • Django 學(xué)習(xí)小組:基于類的通用視圖詳解(一)

    摘要:本教程首先介紹兩個(gè)項(xiàng)目中遇到的通用視圖和。語句的作用是添加了到上下文中,還要把默認(rèn)的一些上下文變量也返回給視圖函數(shù),以便其后續(xù)處理。 通過三周的時(shí)間我們開發(fā)了一個(gè)簡(jiǎn)單的個(gè)人 Blog,教程地址: 第一周:Django 學(xué)習(xí)小組:博客開發(fā)實(shí)戰(zhàn)第一周教程 —— 編寫博客的 Model 和首頁面 第二周:Django 學(xué)習(xí)小組:博客開發(fā)實(shí)戰(zhàn)第二周教程 —— 博客詳情頁面和分類頁面 第三周:D...

    atinosun 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<