Django之博客系統:增加評論


 

3既然是博客,那肯定就有留言評論系統.在這一章就來建立一個評論系統.

1 創建一個模型來保存評論

2 創建一個表單來提交評論並且驗證輸入的數據

3 添加一個視圖函數來處理表單和保存新的評論到數據庫

4 編輯帖子模板來展示評論列表以及用來添加新評論的表單

 

首先來創建一個模型來存儲評論

class Comment(models.Model):

    post=models.ForeignKey(Post,related_name='comments')

    name=models.CharField(max_length=80)

    email=models.EmailField()

    body=models.TextField()

    created=models.DateTimeField(auto_now_add=True)

    updated=models.DateTimeField(auto_now=True)

    active=models.BooleanField(default=True)

    class Meta:

        ordering = ('created',)

    def __str__(self):

        return 'Comments by {} on {}'.format(self.name,self.post)

這就是我們增加評論的模型,其中最關鍵的是post,通過ForeignKeyCommentPost關聯了起來,關聯關系是多對一,原因是一個博客是有多個評論的.定義好之后,我們就可以通過commens.post來取得對應的帖子.以及通過postcomments.all()來取回一個帖子所有的評論.如果你沒有定義related_name屬性,Django會使用這個模型(model)的名稱加上*_set*(在這里是:comment_set)來命名從相關聯的對象反向定位到這個對象的manager

接下來完成數據遷移

zhf@zhf-maple:~/py_prj/mysite$ python manage.py makemigrations blog

Migrations for 'blog':

  blog/migrations/0002_auto_20180303_1216.py

    - Create model Comment

    - Alter field author on post

    - Alter field body on post

    - Alter field created on post

    - Alter field publish on post

    - Alter field status on post

    - Alter field title on post

    - Alter field updated on post

    - Add field post to comment

zhf@zhf-maple:~/py_prj/mysite$ python manage.py migrate

Operations to perform:

  Apply all migrations: admin, auth, blog, contenttypes, sessions

Running migrations:

  Applying blog.0002_auto_20180303_1216... OK

 

同步增加一個評論的管理並在后台進行注冊admin.site.register(Comment,CommentAdmin)

class CommentAdmin(admin.ModelAdmin):

    list_display = ('name','email','post','created','active')

    list_filter = ('active','created','updated')

    search_fields = ('name','email','body')

 

 

創建表單:

在這里的表單和前面的郵件分享不太一樣,這里通過模型來創建表單

from .models import Comment

class CommentsForm(forms.ModelForm):

    class Meta:

        model=Comment

        fields=('name','email','body')

根據模型(model)創建表單,我們只需要在這個表單的Meta類里表明使用哪個模型(model)來構建表單。Django將會解析model並為我們動態的創建表單。每一種模型(model)字段類型都有對應的默認表單字段類型。表單驗證時會考慮到我們定義模型(model)字段的方式。Django為模型(model)中包含的每個字段都創建了表單字段。然而,使用fields 列表你可以明確的告訴框架你想在你的表單中包含哪些字段,或者使用exclude 列表定義你想排除在外的那些字段。對於我們的CommentForm來說,我們在表單中只需要name,email,body字段,因為我們只需要用到這3個字段讓我們的用戶來填寫。

 

視圖中操作ModelForm

根據模型

def post_list_page(request):

    object_list = Post.objects.all()

    paginator = Paginator(object_list, 1)  # 3 posts in each page

    page = request.GET.get('page')

    new_comment = None

    try:

        posts = paginator.page(page)

        comments=posts.object_list[0].comments.filter()

 

    except PageNotAnInteger:

        posts = paginator.page(1)

        comments = posts.object_list[0].comments.filter()

 

    except EmptyPage:

        posts = paginator.page(paginator.num_pages)

    id = posts.object_list[0].id

    post = get_object_or_404(Post, id=id, status='published')

    if request.method == 'POST':

        comment_form = CommentsForm()

        if comment_form.is_valid():

            new_comment = comment_form.save(commit=False)

            new_comment.post = post

            new_comment.save()

    else:

        comment_form = CommentsForm()

    return render(request,

                  'post/list.html',

                  {'page': page,

                   'posts': posts,

                   'comments':comments,

                   'new_comment': new_comment,

                   'comment_form': comment_form,

                   })

 

 

通過comments=posts.object_list[0].comments.filter()得到每個博客對應的評論實例

2 id = posts.object_list[0].id得到每個博客實例的id,並通過id得到Post實例

通過上傳的CommentsForm表單數據將評論和博客連接起來

(1)我們通過調用這個表單的save()方法創建一個新的Comment對象

new_comment = comment_form.save(commit=False)

Save()方法創建了一個表單鏈接的model的實例,並將它保存到數據庫中。如果你調用這個方法時設置commit=False,你創建的模型(model)實例不會即時保存到數據庫中。當你想在最終保存之前修改這個model對象會非常方便,我們接下來將做這一步驟。save()方法是給ModelForm用的,而不是給Form實例用的,因為Form實例沒有關聯上任何模型(model

為剛才的評論分配一個帖子

new_comment.post = post

(3) 最后,我們用下面的代碼將新的評論保存到數據庫中:

new_comment.save()

 

更新模板

既然帖子有了評論功能,現在我們需要修改我們的list模板來適應這個功能。需要呈現如下功能

評論總數

顯示評論的列表

顯示一個表單給用戶來添加新的評論

 

前面視圖傳遞的comments參數。通過with comments.count as total_comments語句將評論的個數傳遞給total_comments.這樣就能顯示具體有多少個評論

      {% with comments.count as total_comments %}

  <h2>

{{ total_comments }} comment{{ total_comments|pluralize }}

 

現在加入評論列表我們使用{% for %}模板(template)標簽(tag)來循環所有的評論。如果comments列為空我們會顯示一個默認的信息,告訴我們的用戶這篇帖子還沒有任何評論。我們使用 {{ forloop.counter }}變量來枚舉所有的評論,在每次迭代中該變量都包含循環計數。之后我們顯示發送評論的用戶名,日期,和評論的內容。

      {% for comment in comments %}

  <div class="comment">

    <p class="info">

      Comment {{ forloop.counter }} by {{ comment.name }}

      {{ comment.created }}

    </p>

    {{ comment.body|linebreaks }}

  </div>

{% empty %}

  <p>還沒有評論</p>

{% endfor %}

 

最后,你需要渲染表單或者顯示一條成功的信息來代替之前的內容。在之前的代碼后面添加如下內容

      {% if new_comment %}

  <h2>Your comment has been added.</h2>

  {% else %}

  <h2>添加新評論</h2>

  <form action="/blog/{{ p.id }}/comment/" method="post">

    {{ comment_form.as_p }}

    {% csrf_token %}

    <input type="submit" value="增加評論">

  </form>

{% endif %}

如果new_comment對象存在,我們會展示一條成功信息因為成功創建了一條新評論。否則,我們用段落<p>元素渲染表單中每一個字段

 

下面來測試下功能:

進入博客,此時還沒有評論,因此顯示0個評論。在下面有添加評論的界面

2在評論表單中填入信息,點擊增加評論。成功的話顯示評論已經添加成功的頁面

3 此時在回到帖子的頁面,可以看到添加的評論

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM