在Django中计算查询集中所有值的总和

3

我正在编写一个Django应用程序,其中有两个类:评论和对该评论的回复。该回复存储在评论的ManyToMany字段中。

这是我的评论类:

class Review(models.Model):
    title = models.CharField(max_length = 30)
    replies = models.ManyToManyField(Reply)

    def __str__(self):
        return self.title

这是我的回复类:

class Reply(models.Model):
    rating = models.DecimalField(decimal_places=1, 
                                 max_digits = 2,
                                 validators = [MaxValueValidator(5), MinValueValidator(0)],
                                 default = 0
                                )
    text_reply = models.TextField(max_length = 200)

我想做的一件事情是将某个评论的所有评分进行计算,并计算这些数字的平均值。我尝试通过以下方式来实现:

def calculate_average():
    objects = Review.objects.all()
    average = 0
    length = 0
    for reply in objects:
        average += reply.replies.rating
        length += 1
    return average/length

回溯

C:\Users\Will Treston\gd\LesRev\lesssonreview>python manage.py runserver
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x03363540>
Traceback (most recent call last):
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\utils\autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\commands\runserver.py", line 113, in inner_run
    autoreload.raise_last_exception()
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\utils\autoreload.py", line 249, in raise_last_exception
    six.reraise(*_exception)
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\utils\six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\utils\autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\__init__.py", line 27, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\apps\registry.py", line 115, in populate
    app_config.ready()
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\admin\apps.py", line 23, in ready
    self.module.autodiscover()
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\admin\__init__.py", line 26, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\utils\module_loading.py", line 50, in autodiscover_modules
    import_module('%s.%s' % (app_config.name, module_to_search))
  File "C:\Users\Will Treston\AppData\Local\Programs\Python\Python36-32\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 978, in _gcd_import
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load
  File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
  File "C:\Users\Will Treston\gd\LesRev\lesssonreview\review\admin.py", line 5, in <module>
    class ReviewAdmin(admin.ModelAdmin):
  File "C:\Users\Will Treston\gd\LesRev\lesssonreview\review\admin.py", line 8, in ReviewAdmin
    list_display = ["title", Review.calculate_average()]
  File "C:\Users\Will Treston\gd\LesRev\lesssonreview\review\models.py", line 46, in calculate_average
    average += reply.replies.rating
AttributeError: 'ManyRelatedManager' object has no attribute 'rating'

请包含完整的回溯信息... - Raja Simon
@RajaSimon,我已经添加了!抱歉之前提交有误! - wtreston
1个回答

1
计算特定评论的评分,
result = {}
objects = Review.objects.all()
for review in objects:
    average = 0
    length = 0
    for reply in review​.replies.all():
        average += reply.rating
        length += 1
    average /= length
    result.update({review.title, average})

如果您正在寻找一个模型属性来计算单个模型的总和,那么
class Review(models.Model):

    def calculate_rating(self):
        average = 0
        length = 0
        for reply in self​.replies.all():
            average += reply.rating
            length += 1
        if average:
            average /= length
        return average

这样会不会在每个评论中都计算平均值?如果是的话,我希望将其放在我的评论类中,并仅计算该单个评论的平均结果。 - wtreston
是的,它会为每个评论计算评分。 - zaidfazil
我该如何计算单个评论的评分? - wtreston
更新了答案。 - zaidfazil
Fazil,如果我想在admin.py页面中调用这个模型属性,我该怎么做?我该如何告诉它引用哪个实例/评论? - wtreston
你可以编写一个模型管理类并将其添加到list_display中... 更多细节请参考此问题,https://dev59.com/83VC5IYBdhLWcg3w2lCI - zaidfazil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接