我有一个简单的社交媒体应用程序,与用户,帖子,投票后模型.
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
...
@property
def score(self):
total = 0
for vote in PostVote.objects.all():
if vote.post == self:
total += vote.vote
return total
def get_num_upvotes(self):
return PostVote.objects.filter(post=self, vote=1).count()
def get_num_downvotes(self):
return PostVote.objects.filter(post=self, vote=-1).count()
class PostVote(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
post = models.ForeignKey(Post, on_delete=models.SET_NULL, null=True)
vote = models.IntegerField()
在我的views.py中,我试图计算出排名靠前的帖子,并按分数排序.以下是视图代码.
class ListCreatePostAPIView(ListCreateAPIView):
serializer_class = PostSerializer
permission_classes = (IsGoodUser | IsAdminUser,)
def get_queryset(self):
try:
queryset = Post.objects.all().exclude(user=None)
queryset = list(queryset)
queryset.sort(key=operator.attrgetter("score"), reverse=True)
return queryset
except:
return Post.objects.none()
在序列化程序中,我还会再次重新计算并返回分数,因为我希望将它传递给我的前端.
class PostSerializer(serializers.ModelSerializer):
score = serializers.SerializerMethodField()
num_upvotes = serializers.SerializerMethodField()
num_downvotes = serializers.SerializerMethodField()
def get_score(self, obj):
return obj.get_score()
def get_num_upvotes(self, obj):
return obj.get_num_upvotes()
def get_num_downvotes(self, obj):
return obj.get_num_downvotes()
class Meta:
model = Post
fields = (
"score",
"num_upvotes",
"num_downvotes",
)
我知道我重新计算分数的次数太多了,因为返回50个虚假帖子/1250个虚假帖子需要3-4秒,但我如何才能真正提高效率呢?我try 过PREFETCH_Related,但我想不出如果对属性进行排序该如何使用它.我真的迷路了,如果有任何帮助,我将不胜感激.