gpt4 book ai didi

django - 在 Django 中查询每个用户每个帖子的最新投票

转载 作者:行者123 更新时间:2023-11-29 13:54:33 27 4
gpt4 key购买 nike

我有一个投票系统,用户可以在其中对帖子投赞成票或反对票。投票将用于计算,因此我需要以日志格式存储它们,即,我将每张投票保存在它自己的表中。

像这样:

class PointLog(models.Model):
post = models.ForeignKey(Post, db_index=True)
points = models.IntegerField(db_index=True)
user = models.ForeignKey(User, blank=True, null=True)
time = models.DateTimeField(auto_now_add=True, db_index=True)
data = models.IntegerField() # -1, 0 or 1

现在我需要显示 20 个帖子,以及用户最后一次投票。

我正在使用 django-rest-framework,因此我可以使用如下所示的序列化程序字段; uservote = serializers.SerializerMethodField(),连同如下函数:

def get_uservote(self, obj):
user = self.context['request'].user
vote = PointLog.objects.only('data').filter(user=user, post=obj).last()
return vote.data if vote else 0

但这将对每个帖子执行 1 次数据库查询,我希望有更好的解决方案。

通过将查询集保存在 self.context 中,我可以为每次运行 get_uservote 时保存一个数据库查询,这样就涵盖了这一部分。但是,我如何才能执行基于项目列表的查询,返回另一个表中的所有 latest 数据。

开始是 PointLog.objects.filter(user=user, post__in=posts),但接下来呢?这甚至可以在 1 个查询中使用原始 SQL 吗?

更新 1:PointLog.objects.filter(...).order_by('post__id').distinct('post__id') 会有点这样做,除了我不认为我能保证得到 最新投票。如果我使用 order_by('pk')(或'time'),我不能使用 distinct('post__id') 因为我会得到一个 sql 错误(ProgrammingError: SELECT DISTINCT ON表达式必须匹配初始 ORDER BY 表达式)

最佳答案

我找到了一个只添加了 1 个额外查询的解决方案。

完整的 get_uservote 将是;

def get_uservote(self, obj):
user = self.context['request'].user
if user.is_authenticated():
if not self.context.get('get_uservote_data'):
self.context['get_uservote_data'] = {i.post_id: i.data for i in PointLog.objects.filter(user=user, post__in=self.instance).order_by('post__id', '-pk').distinct('post__id')}
return self.context['get_uservote_data'].get(obj.id, 0)
else:
return 0 # Return 0 as "not voted" if not logged in

请注意,我们在这里使用了一些技巧;

  • 将数据存储在 self.context['get_uservote_data'] 中,这样我们只需运行一次查询。
  • 使用 i.post_id 作为我们数据的键,而不是 i.post.id。在这里询问 i.post.id 会触发每个项目 1 个查询。
  • self.instance 是包含我们要过滤的所有帖子的查询集。

这一切都导致了一个如下所示的查询:

SELECT DISTINCT ON ("post_pointlog"."post_id") "post_pointlog"."id",
"post_pointlog"."post_id",
"post_pointlog"."data"
FROM "post_pointlog"
WHERE ( "post_pointlog"."user_id" = 20
AND "post_pointlog"."post_id" IN ( 1, 2, 3, 4 ) )
ORDER BY "post_pointlog"."post_id" ASC,
"post_pointlog"."id" DESC

关于django - 在 Django 中查询每个用户每个帖子的最新投票,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34863690/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com