2017-08-27 140 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?这是你需要决定的。 –