在 django rest 框架序列化程序中优化 django 相关集平均值
Optimizing django related set average in a django rest framework serializer
我正在使用 Django 1.8 和 Django Rest Framework。
我有两个模型:Marker
和 MarkerComment
。
class Marker(models.Model):
# a bunch of fields here...
def rating(self):
"""
Return the mean rating from all comments
"""
return self.comments.aggregate(models.Avg('rating'))['rating__avg']
class MarkerComment(models.Model):
# a few fields here...
marker = models.ForeignKey(Marker, blank=False, related_name='comments')
rating = models.PositiveSmallIntegerField(blank=False)
在我的序列化程序中,我有这样的东西:
class MarkerSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Marker
fields = (
'url', 'pk', 'created', 'name', 'category', 'rating', ...
)
read_only_fields = ('rating')
我的序列化程序的 list
查询花费的时间太长,因为它查询每个标记以获取平均值。查看 NewRelic:
这是 运行 我结果集中每个标记的查询:
SELECT AVG("maps_markercomment"."rating") AS "rating__avg" FROM "maps_markercomment" WHERE "maps_markercomment"."marker_id" = 1788
如果我不使用 Django Rest Framework,我可能会做一些事情来一次性获得所有评分,例如
Marker.objects.filter(...).annotate(rating=Avg('comments__rating'))
所以我的问题是:我有什么选择可以让它更快?有没有办法在仍然使用序列化程序的同时将所有这些都放在一个 SQL 查询中?我必须如何缓存每个标记的评分?
您可以将所需的优化应用于视图中的查询集,因为此优化的查询集最终将传递给序列化程序。
我正在使用 Django 1.8 和 Django Rest Framework。
我有两个模型:Marker
和 MarkerComment
。
class Marker(models.Model):
# a bunch of fields here...
def rating(self):
"""
Return the mean rating from all comments
"""
return self.comments.aggregate(models.Avg('rating'))['rating__avg']
class MarkerComment(models.Model):
# a few fields here...
marker = models.ForeignKey(Marker, blank=False, related_name='comments')
rating = models.PositiveSmallIntegerField(blank=False)
在我的序列化程序中,我有这样的东西:
class MarkerSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Marker
fields = (
'url', 'pk', 'created', 'name', 'category', 'rating', ...
)
read_only_fields = ('rating')
我的序列化程序的 list
查询花费的时间太长,因为它查询每个标记以获取平均值。查看 NewRelic:
这是 运行 我结果集中每个标记的查询:
SELECT AVG("maps_markercomment"."rating") AS "rating__avg" FROM "maps_markercomment" WHERE "maps_markercomment"."marker_id" = 1788
如果我不使用 Django Rest Framework,我可能会做一些事情来一次性获得所有评分,例如
Marker.objects.filter(...).annotate(rating=Avg('comments__rating'))
所以我的问题是:我有什么选择可以让它更快?有没有办法在仍然使用序列化程序的同时将所有这些都放在一个 SQL 查询中?我必须如何缓存每个标记的评分?
您可以将所需的优化应用于视图中的查询集,因为此优化的查询集最终将传递给序列化程序。