我正在学习如何在Django上使用post_save信号。虽然我没有收到任何错误,但我想做的事情是行不通的。
我有一个模型(模型),它应该聚合并平均Review模型中的评级,并将该数字保存在名为“average_rating”的字段中。
我希望一旦用户对“评论”模型提供评级并且在“模型”模型上自动计算和更新平均评级,就可以进行平均。
我知道我可以用post_save信号做到这一点。但我不确定如何。
我怎样才能做我想做的事?
提前致谢。
models.py
from django.db import models
from django.db.models import Func, Avg
from django.urls import reverse
from django.template.defaultfilters import slugify
from django.db.models.signals import post_save
from django.dispatch import receiver
class Model(models.Model):
name = models.CharField(max_length=55, default='')
slug = models.SlugField(unique=True)
average_rating = models.DecimalField(decimal_places=1,
max_digits=2,
default=0.0,
blank=True,
null=True)
def __str__(self):
return self.name
def save(self, *args, **kwargs):
self.average_rating = self.review_set.aggregate(
rounded_avg_rating=Round(Avg('rating')))['rounded_avg_rating']
self.slug = (slugify(self.name))
super(Model, self).save(*args, **kwargs)
class Review(models.Model):
RATING_CHOICES = [
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5'),
]
model = models.ForeignKey(Model,
null=True)
rating = models.IntegerField(choices=RATING_CHOICES,
default=1)
review_date = models.DateField(auto_now_add=True)
reviewer = models.ForeignKey(User,
null=True,
related_name = 'review_user')
comment = models.TextField(default='')
class Meta:
verbose_name_plural = 'Reviews'
verbose_name = 'Review'
def __str__(self):
return self.model.name
@receiver(post_save, sender=Review)
def update_average_rating(sender, instance, **kwargs):
instance.average_rating = Review.objects.aggregate(
rounded_avg_rating=Round(Avg('rating')))['rounded_avg_rating']
更新
使用RajKris提供的解决方案,我得到了这个:
class Review(models.Model):
....
def save(self, *args, **kwargs):
Model.save(avg_rating_flag=True)
super(Review, self).save(*args, **kwargs)
现在我收到此错误:TypeError:save()缺少1个必需的位置参数:'self'
RajKris的更新答案解决了我的问题。像魅力一样。
def save(self, *args, **kwargs):
super(Review, self).save(*args, **kwargs)
model_obj = self.model
model_obj.average_rating = model_ob.review_set.aggregate(
rounded_avg_rating=Round(Avg('rating')))['rounded_avg_rating']
model_obj.save()
答案 0 :(得分:1)
在您的评论保存功能中:
def save(self, *args, **kwargs):
super(Review, self).save(*args, **kwargs)
model_obj = self.model
model_obj.average_rating = model_obj.review_set.aggregate(
rounded_avg_rating=Round(Avg('rating')))['rounded_avg_rating']
model_obj.save()
这里发生的是,每次创建审阅对象时,相应的Model对象都会使用新的平均评级进行更新。