简体   繁体   English

在Django模型中生成平均评分,然后与其他模型一起返回

[英]Generate average for ratings in Django models and return with other model

I'm working on a project using Python(3.7) and Django(2.1) in which I'm trying to implement a rating system. 我正在使用Python(3.7)和Django(2.1)开发一个项目,我正在其中实施评分系统。

Note: I have searched a lot and taken a look at various related questions but couldn't find any solution to my specific problem, so don't mark this as duplicated, please! 注意:我进行了很多搜索,并研究了各种相关问题,但找不到针对我特定问题的任何解决方案,因此请不要将其标记为重复项!

I have two models as: 我有两种模型:

From models.py : models.py

class Gig(models.Model):
    CATEGORY_CHOICES = (
        ('GD', 'Graphic & Design'),
        ('DM', 'Digital Marketing'),
        ('WT', 'Writing & Translation'),
        ('VA', 'Video & Animation'),
        ('MA', 'Music & Audio'),
        ('PT', 'Programming & Tech'),
        ('FL', 'Fun & Lifestyle'),
    )

    title = models.CharField(max_length=500)
    category = models.CharField(max_length=255, choices=CATEGORY_CHOICES)
    description = models.CharField(max_length=1000)
    price = models.IntegerField(blank=False)
    photo = models.FileField(upload_to='gigs')
    status = models.BooleanField(default=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.title

class GigReview(models.Model):
    RATING_RANGE = (
        ('1', '1'),
        ('2', '2'),
        ('3', '3'),
        ('4', '4'),
        ('5', '5')
    )
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    gig = models.ForeignKey(Gig, on_delete=models.CASCADE, related_name='rates')
    order = models.ForeignKey(Order, on_delete=models.CASCADE, null=True)
    rating = models.IntegerField(choices=RATING_RANGE,)
    content = models.CharField(max_length=500)

    def __str__(self):
        return self.content

From views.py : views.py

def home(request):
    gigs = Gig.objects.filter(status=True)
    return render(request, 'home.html', {'gigs': gigs})

So, every Gig has many reviews and I want to return the average rating for each gig to the template, how Can I achieve that? 所以,每Gig有很多评论,我想返回average评级为每个演出的模板,我怎么能做到这一点?

A simple annotation should get it done in one query (rather than one per Gig when using a property): 一个简单的注释应该在一个查询中完成它(而不是在使用属性时每个Gig一个查询):

from django.db.models import Avg

gigs = (Gig.objects
    .filter(status=True)
    .annotate(avg_review=Avg('rates__rating'))
)

If you want to be able to access the average review value on model level, you could add a property field that aggregates the average value through related models in the Gig -model: 如果您希望能够访问模型级别的平均评论值,则可以在Gig -model中添加一个属性字段,以通过相关模型汇总平均值:

class Gig(models.Model):
    ...

    @property
    def average_rating(self):
        return self.rates.all().aggregate(Avg('rating')).get('rating__avg', 0.00)
        # Change 0.00 to whatever default value you want when there
        # are no reviews.

And in the template access the value with average_rating . 然后在模板中访问带有average_rating的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM