首页 > 解决方案 > Django:不同字段的最旧条目

问题描述

我有以下模型(出于示例目的而简化):

class Execution(models.Model):
    name = models.CharField(null=False, max_length=30)
    creation_date = models.DateTimeField(auto_now_add=True, null=False)

class Post(models.Model):
    class Meta:
        unique_together = ('code', 'secondary_code', 'execution')

    code = models.CharField(null=False, max_length=30)
    secondary_code = models.CharField(null=False, max_length=3)
    execution = models.ForeignKey(Execution, null=False, on_delete=models.CASCADE)
    text = models.TextField()

在数据库上,我有以下实例:

execution_1 = Execution('Execution 1', '2019-01-01')
execution_2 = Execution('Execution 2', '2019-01-02')

post_1 = Post('123', '456', execution_1, 'lorem')
post_2 = Post('789', '999', execution_1, 'ipsum')
post_3 = Post('789', '999', execution_2, 'dolor')

我想检索所有帖子,对于codeand是唯一的secondary_code(因此,只有一个在 and 之间post_2post_3因为它们具有相同的codeand secondary_code)并选择一个基于最旧的帖子execution(所以,在这种情况下,我想要post_1andpost_2因为executionofpost_2较旧execution的那个post_3)。

我需要同时支持 Postgres 和 sqlite3 3.18.0,所以,由于 sqlite,我不能使用窗口函数。

这个怎么做?

标签: djangodjango-models

解决方案


newer_post = Post.objects.filter(code=OuterRef('code'), 
    secondary_code=OuterRef('secondary_code'), 
    execution__creation_date__gt=OuterRef('execution_dt'), 
)

posts = Post.objects.all().annotate(execution_dt=execution__creation_date, )

latest_posts = posts.\
    annotate(has_newer_post=Exists(newer_post), ).\
    filter(has_newer_post=False, )

推荐阅读