将 Django 查询集中的所有值相加
Posted
技术标签:
【中文标题】将 Django 查询集中的所有值相加【英文标题】:Add up all the values in a queryset in Django 【发布时间】:2017-11-10 12:40:49 【问题描述】:我正在编写一个 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'
【问题讨论】:
请包含完整的回溯... @RajaSimon 现已添加!抱歉提交有误! 【参考方案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
【讨论】:
这不会计算每条评论的平均值吗?如果是这样,我希望它出现在我的复习课上,并且只计算那条复习的平均结果。 是的,它会计算每条评论的评分。 我将如何计算单个评论的评分?编辑:刚刚看到你会更新它!谢谢 更新了答案 Fazil,如果我想在 admin.py 页面中调用这个模型属性,我该怎么做呢?我如何告诉它要引用哪个实例/评论?以上是关于将 Django 查询集中的所有值相加的主要内容,如果未能解决你的问题,请参考以下文章