2017-08-27 102 views
0

我正在製作一個博客,用戶可以在我的博客上留言/評分。我想顯示該特定帖子的所有評分的平均值。我怎麼做?django - 在模板中顯示平均值

models.py

class Post(models.Model): 
    STATUS_CHOISES = (

     ('draft', 'Draft'), 
     ('published', 'Published'), 

     ) 
    category = models.ForeignKey(Category) 
    title = models.CharField(max_length=250) 
    slug = models.SlugField(max_length=250, unique=True) 
    content = models.TextField() 
    seo_title = models.CharField(max_length=250) 
    seo_description = models.CharField(max_length=160) 
    author = models.ForeignKey(User, related_name='blog_posts', default=settings.AUTH_USER_MODEL) 
    published = models.DateTimeField(default=timezone.now) 
    created = models.DateTimeField(auto_now_add=True) 
    updated = models.DateTimeField(auto_now=True) 
    status = models.CharField(max_length=9, choices=STATUS_CHOISES, default='draft') 

    def get_absolute_url(self): 
     return reverse('blog:post_detail', args=[self.slug]) 


    def __str__(self): 
     return self.title 



class Comment(models.Model): 
    difficulty_rating_choices = (

     (1, 'Very Easy'), 
     (2, 'Easy'), 
     (3, 'Moderate'), 
     (4, 'Hard'), 
     (5, 'Very Hard'), 

    ) 

    workload_rating_choices = (

     (1, 'Very Light'), 
     (2, 'Light'), 
     (3, 'Moderate'), 
     (4, 'Heavy'), 
     (5, 'Very Heavy'), 

    ) 

    book_rating_choices = (

     (1, '$'), 
     (2, '$$'), 
     (3, '$$$'), 
     (4, '$$$$'), 
     (5, '$$$$$'), 

    ) 

    attendance_rating_choices = (

     (1, 'Not Required'), 
     (2, 'Required'), 


    ) 
    post = models.ForeignKey(Post, related_name="comments") 
    user = models.CharField(max_length=250) 
    email = models.EmailField() 
    title = models.CharField(max_length=250) 
    body = models.TextField() 
    created = models.DateTimeField(auto_now_add=True) 
    approved = models.BooleanField(default=False) 
    difficulty_rating = models.IntegerField(choices=difficulty_rating_choices) 
    workload_rating = models.IntegerField(choices=workload_rating_choices) 
    book_rating = models.IntegerField(choices=book_rating_choices) 
    attendance_rating = models.IntegerField(choices=attendance_rating_choices) 


    def approved(self): 
     self.approved = True 
     self.save() 

    def __str__(self): 
     return self.title 

views.py

def add_comment(request, slug): 
    post = get_object_or_404(Post, slug=slug) 
    if request.method == 'POST': 
     form = CommentForm(request.POST) 
     if form.is_valid(): 
      comment = form.save(commit=False) 
      comment.post = post 
      comment.save() 
      return redirect('blog:post_detail', slug=post.slug) 
    else: 
     form = CommentForm() 
    template = "blog/post/add_comment.html" 
    context = {'form': form} 
    return render(request, template, context) 

模板

<h1>Difficulty: <h1> 
     <h1>Workload: <h1> 
     <h1>Book Cost: <h1> 
     <h1>Attendance: <h1> 

     <hr> 
     <h2>{{ post.title }}</h2> 
     <p>Written by {{ post.author }} on {{ post.published }}</p> 
     <hr> 
     {{ post.content|linebreaks }} 
     <hr> 
     <h2>Comments</h2> 
     <p>Total number of comments: {{ post.comments.count }}</p> 
     <a href="{% url 'blog:add_comment' slug=post.slug %}">Leave a comment</a> 
     {% for comment in post.comments.all %} 


      <p>Title: {{ comment.title }}</p> 
      <p>Review: {{ comment.body }}</p> 
      <p>Date: {{ comment.created }}</p> 
      <p>Posted by: {{ comment.user }}</p> 
      <p>Difficulty: {{ comment.get_difficulty_rating_display }}</p> 
      <p>Workload: {{ comment.get_workload_rating_display }}</p> 
      <p>Book Cost: {{ comment.get_book_rating_display }}</p> 
      <p>Attencance: {{ comment.get_attendance_rating_display }}</p> 
      <hr> 

     {% empty %} 
      <p>There are no comments yet. Be the first one to comment!</p> 

     {% endfor %} 

我想,我的每個4個標準(difficulty_rating,workload_rating,book_rating顯示的平均值, attendance_rating)在我的模板的頂部。我會怎麼做呢?到目前爲止,我還沒有弄清楚它。

這是在模板級完成的嗎?我必須編輯我的views.py嗎?或者甚至可能是模型本身?

+0

計算在視圖中的平均水平,在它傳遞給模板作爲單獨的項目。 –

回答

1

你可以在你的Post模型編寫的輔助方法:

from django.db.models import Avg 

class Post(models.Model): 
    # ... 
    def avg_ratings(self): 
     return self.comments.aggregate(
      Avg('difficulty_rating'), 
      Avg('workload_rating'), 
      Avg('book_rating'), 
      Avg('attendance_rating'), 
     ) 

然後在模板,你可以這樣做:

{% with avg_ratings=post.avg_ratings %} 
    {{ avg_ratings.difficulty_rating__avg }} 
    {{ avg_ratings.workload_rating__avg }} 
    {{ avg_ratings.book_rating__avg }} 
    {{ avg_ratings.attendance_rating__avg }} 
{% endwith %} 
+0

工作!謝謝!如果我想要展示他們的人類可讀對象呢?在我的選擇中,例如,當值爲3時,我在book_rating中可讀取'$$$'。有沒有辦法做到這一點?我的猜測是它將不得不將它舍入到最接近的整數並離開? – dmandres

+0

沒問題!如果卡住了,請爲此創建一個單獨的問題,但是,您需要將其四捨五入到最接近的整數並從那裏開始。但如果平均值爲2.5,你會認爲它是3還是2?這是你需要決定的。 –