如何按DateTimeField排序并基于ForeignKey选择不同的元素?

2024-10-16 17:17:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用PostgreSQL作为Django项目的数据库。我有以下型号:

class Food(models.Model):
    """Stores a food entry"""
    name = models.CharField(max_length=50)
    image_id = models.CharField(max_length=20)
    description = models.TextField()

class SurveyResult(models.Model):
    """Stores survey food result based on emoji and personality"""
    emoji = models.CharField(max_length=10)
    personality = models.CharField(max_length=50)
    food = models.ForeignKey(Food, on_delete=models.CASCADE)
    timestamp = models.DateTimeField(auto_now_add=True)
    rating = models.PositiveSmallIntegerField(default=0)

我需要编写一个按'-timestamp'排序的查询,然后只获取'food'的不同值。这就是我所尝试的:

SurveyResult.objects.order_by('-timestamp').distinct('food')

但是,我得到以下错误:

ProgrammingError: SELECT DISTINCT ON expressions must match initial ORDER BY expressions LINE 1: SELECT DISTINCT ON ("recommender_surveyresult"."food_id") "r...

我读了几个问题的答案,我发现一个答案基本上是这样的:

SurveyResult.objects.order_by('food', '-timestamp').distinct('food')

然而,我并没有得到我想要的东西,那就是最新的SurveyResult对象,它们具有不同的food。你知道吗

我怎样才能做到这一点?你知道吗

假设我的数据库中有下表:

# surveyresults
id emoji personality food timestamp            rating
1  :)    Famous US     1  2018-01-01 - 9:00      1
2  XD    Famous CN     3  2018-01-01 - 9:10      2
3  :)    Famous NZ     5  2018-01-01 - 9:15      3
4  :(    Famous FR     5  2018-01-01 - 9:35      4
5  XD    Famous US     1  2018-01-01 - 9:45      5
6  ;)    Famous JP     4  2018-01-01 - 9:55      5
7  :o    Famous SP     4  2018-01-01 - 10:00     5

查询应提供以下信息:

id emoji personality food timestamp            rating
7  :o    Famous SP     4  2018-01-01 - 10:00     5
5  XD    Famous US     1  2018-01-01 - 9:45      5
4  :(    Famous FR     5  2018-01-01 - 9:35      4
2  XD    Famous CN     3  2018-01-01 - 9:10      2

我也想知道,是否有可能实现这一点只是一个查询。你知道吗


Tags: id数据库foodmodelslengthmaxtimestampus
2条回答

您可以使用subquery实现这一点,如下所示

SurveyResult.objects.filter(
    id__in=SurveyResult.objects.order_by('food', '-timestamp').distinct('food')
).order_by('-timestamp')

说明:

所以基本上subquery涉及对多个query的求值,在您的例子中,我们正在求值两个查询。上述queryset的SQL如下所示

SELECT "id", "emoji", "personality", "food", "timestamp", "rating"
FROM "appname_surveyresult"
WHERE id IN (
    SELECT "id", DISTINCT ON ("food") 
    FROM "appname_surveyresult"
    ORDER BY "food" ASC, "timestamp" DESC 
)
ORDER BY "timestamp" DESC

因此,首先内部(就像数学一样)查询求值,其结果将成为外部查询的输入,从而在不同的中生成最新的。阅读this了解更多信息。你知道吗

您可以考虑向SurveyResults模型添加一个元类,然后在那里指定您的顺序

class SurveyResult(models.Model):
    ...

   class Meta:
        ordering = ('-timestamp',)

相关问题 更多 >