2017-08-23 4 views
1

要するに、ListViewを使用して、教師のリストと対応する評価を表示したいと思います。ListViewは、ForeignKeysから取られたリストの各項目の評価を返します

現在、私はmodels.pyを持っている:

class Teacher(models.Model): 
    user = models.OneToOneField(User, on_delete=models.PROTECT, related_name='Teacher') 
    availability = models.BooleanField(default=False) 

class Review(models.Model): 
    teacher = models.ForeignKey(Teacher) 
    student = models.OneToOneField(Student, on_delete=models.PROTECT, related_name='Student') 
    star = models.IntegerField(default=5) 
    body = models.TextField() 

私のリストビューでは、私がすることget_queryset()関数を定義:

class IndexView(ListView): 

    def get_queryset(self): 
     """Return the last five published teachers.""" 
     return Teacher.objects.all()[:5] 

今、私は私が使用できるオブジェクトteacher_listを持っていますテンプレート。

私が使用して、個々の評価の平均採点取得する方法を知っている:私はteacher_idの値を指定し、teacher_listクエリに含めないように今、私は変更する必要が

Review.objects.filter(teacher_id=self.kwargs['pk']).aggregate(Avg('star')) 

ですセット。したがって、teacher_listのすべての教師はteacher.rating属性を持っています。

This Django tutorialは、教師オブジェクトを使用して直接関連するモデルにアクセスできることを示しています。だから先生teacher_listに、私はteacher.star_set.all()を使用してすべてのレビューを見ることができるはずです。私は単純にこの値の平均値を見つけて何とか表示します。

答えて

1

あなたはそれが平均レビュー星です保持しますあなたのTeacherモデルに@propertyを追加することができます:私は、リストに全体をキャスト、なぜあなたが理解するためにthe docsを見て

class Teacher(models.Model): 
    # ... 

    @property 
    def average_review_stars(self): 
     return list(self.review_set.aggregate(Avg('Sum')).values())[0] 
     # self.review_set holds the reviews of the current Teacher 
     # and you just aggregate the average of review stars 

     # You cast the whole result to a list, 
     # because dict_values does not support indexing 
     # and you want the first and only value from this aggregation 

を持つことができます次に[0]にアクセスします。

<ul> 
{% for teacher in teacher_list %} 
    <li>Average rating: {{ teacher.average_review_stars }}</li> 
{% endfor %} 
</ul> 
:それを行うための他の方法は、あなたが自由に、このプロパティにアクセスすることができ、あなたのテンプレートに続いて

self.review_set.aggregate(Avg('Sum')).pop('stars__avg')です

関連する問題