在 django 查询集中查找用户的最新评分

发布于 2024-11-15 19:09:20 字数 616 浏览 2 评论 0原文

我正在寻找一种方法来获取特定人员对所有资源的最新评级。 目前我正在使用像 Rating.objects.filter(Person = person).order_by('-timestamp') 这样的查询 然后将其通过带有资源和用户属性键的 unique_everseen 传递,然后使用 Rating.objects.filter(id__in = uniquelist) 重新查找。有没有更优雅的方法来使用 django 查询集函数来做到这一点? 这些是相关模型。

class Person(models.Model):
    pass

class Resource(models.Model):
    pass

class Rating(models.Model):
    rating = models.IntegerField()
    timestamp = models.DateField()
    resource = models.ForeignKey('Resource')
    user = models.ForeignKey('Person')

我需要保留所有旧的评级,因为其他功能需要能够保留事物如何“变化”的历史记录。

I'm looking for a method to get the most recent rating for a specific Person for all Resources.
Currently I'm using a query like Rating.objects.filter(Person = person).order_by('-timestamp')
then passing that through a unique_everseen with a key on the resource and user attributes and then re-looking up with a Rating.objects.filter(id__in = uniquelist). Is there a more elegant way to do this with the django queryset functions?
These are the relevant models.

class Person(models.Model):
    pass

class Resource(models.Model):
    pass

class Rating(models.Model):
    rating = models.IntegerField()
    timestamp = models.DateField()
    resource = models.ForeignKey('Resource')
    user = models.ForeignKey('Person')

I need to keep all of the old Ratings around since other functions need to be able to keep a history of how things are 'changing'.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

無處可尋 2024-11-22 19:09:20

我不是 100% 清楚您在这里要寻找的内容,您想查找用户对他们评级的所有资源的最新评级吗?如果您可以提供有关 unique_everseen 实际用途的详细信息,这将有助于澄清您正在寻找的内容。

您宁愿从资源角度来看:

resources = Resource.objects.filter(rating__user=person).order_by('-rating__timestamp')
resource_rating = [(resource, resource.rating_set.filter(person=person).get_latest('timestamp')) for resource in resources]

您也许可以使用 Aggregate函数来获取每个资源的最新记录,或者巧妙地使用Q 对象来限制 SQL requests(我的示例可能会为您节省一些请求,并且更加优雅,但它并不像使用原始 SQL 请求生成的那么简单)。在原始 SQL 中,您将使用内部 SELECT 或执行良好的 GROUP BY 来获取最新评级,因此模仿这将是理想的选择。

您还可以创建一个 post_save 信号挂钩 和一个“活动”或“当前” ' 评级模型上的布尔字段,它将迭代与用户/资源匹配的其他评级,并将其“活动”字段设置为 False。即 post_save 挂钩将使用类似以下内容将所有其他评级标记为用户/资源不活动:

if instance.active:
    for rating in Rating.objects.filter(user=instance.user,resource=instance.resource).exclude(id=instance.id):
        rating.active=False
        rating.save()

然后您可以执行一个简单的查询:

Rating.objects.filter(user=person,active=True).order_by('-timestamp')

这将是最经济的查询(即使您在中进行复杂的分组依据/内部选择)原始 SQL(您正在执行比必要的更复杂的查询)。使用布尔字段还意味着您可以为用户的评分提供“前进/后退”/“撤消/重做”行为(如果相关)。

I am not 100% clear on what you are looking for here, do you want to find the most recent rating by a user for all the resources they have rated? If you can provide detail on what unique_everseen actually does it would help to clarify what you are looking for.

You could rather look from a resource perspective:

resources = Resource.objects.filter(rating__user=person).order_by('-rating__timestamp')
resource_rating = [(resource, resource.rating_set.filter(person=person).get_latest('timestamp')) for resource in resources]

You might be able to use Aggregate functions to get to the most recent record per resource, or some clever use of the Q object to limit the SQL requests (my example may save you some requests, and be more elegant but it is not as simple as what you could produce with a raw SQL request). In raw SQL you would be using an inner SELECT or a well executed GROUP BY to get the most recent rating, so mimicking that would be ideal.

You could also create a post_save signal hook and an 'active' or 'current' boolean field on your Rating model, which would iterate other ratings matching user/resource and set their 'active' field to False. i.e. the post_save hook would mark all other ratings as inactive for a user/resource using something like:

if instance.active:
    for rating in Rating.objects.filter(user=instance.user,resource=instance.resource).exclude(id=instance.id):
        rating.active=False
        rating.save()

You could then do a simple query for:

Rating.objects.filter(user=person,active=True).order_by('-timestamp')

This would be the most economical of queries (even if you make the complicated group by/inner select in raw SQL you are doing a more complicated query than necessary). Using the boolean field also means you can provide 'step forward/step backwards'/'undo/redo' behavior for a user's ratings if that is relevant.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文