3

我有一个 Order 模型和 order_event 模型。每个 order_event 都有一个要订购的外键。所以从一个订单实例我可以得到:myorder.order_event_set。我想获取所有订单的列表,但我希望它们按最后一个事件的日期排序。像这样的语句可以按最新事件日期排序:

queryset = Order.objects.all().annotate(
    latest_event_date=Max('order_event__event_datetime')
    ).order_by('latest_event_date')

但是,我真正需要的是按 A SUBSET OF EVENTS 的最新日期排序的所有订单列表。例如,我的事件被分类为“调度”、“处理”等。所以我应该能够获得按最新调度事件排序的所有订单的列表。此 django 文档(https://docs.djangoproject.com/en/dev/topics/db/aggregation/#filter-and-exclude)显示了我如何使用过滤器获取最新的日程安排事件,但这不包括没有日程安排的订单事件。

我想我可以将过滤后的查询集与一个查询集结合起来,其中包括那些缺少调度事件的订单……但我不太确定如何做到这一点。我看到了与使用 python 列表相关的答案,但是拥有一个适当的 django 查询集会更有用(即,对于带有分页的视图等)

编辑回复:评论/建议

class Order(models.Model):
    desc = models.CharField(max_length=30)

class Order_event(models.Model):
    order = models.ForeignKey(Order)
    event_datetime = models.DateTimeField(auto_now_add = True)

另外,我不介意在不止一个声明中这样做。此外,通过 python 而不是 orm 进行排序等是可以的,因为我不使用庞大的数据集。如果可能的话,出于您提到的原因,我宁愿远离 sql​​。组合单独的、排序的查询集似乎很有希望,但我被卡住了。

4

2 回答 2

1

好的,我认为您可以使用额外的方法来实现这一点,但据我所知,不能使用纯数据库无关的 orm。这意味着您必须确保您的 sql 适用于您正在使用的数据库后端,并且要警惕 django 为表名起别名,但这也意味着您可以通过一个查询完成所有操作。

这些方面的东西应该起作用:

latest_event_subquery = 'select max(event_datetime) ' \
                        'from appname_order_event ' \
                        'where appname_order_event.category="scheduling" and ' \
                              'appname_order_event.event_id=appname_order.id'
queryset = Order.objects.extra(select={'latest_event_date': latest_event_subquery}).order_by('latest_event_date')

那有意义吗?

于 2012-12-07T08:29:30.087 回答
1

格雷格的回答很棒,我用了一段时间。但是,我想访问 latest_event 的其他字段。所以,我最终将 latest_event 存储为 Order 的一个字段:

# The latest event
latest_event = db.ForeignKey('whateverapp.Event', editable=False, null=True)

然后我设置了一个信号以在保存时重新计算最新事件:

@receiver(post_save, sender=Event)
def visit_calculate_latest(sender, instance, **kwargs):
    """Recalculate latest event"""
    instance.parent.latest_event = instance.parent.get_latest_event()

get_latest_event() 在哪里进行了查询:

def get_latest_event(self):
    """Return most recent event or None."""
    try:
        return Event.objects.filter(
            parent=self.id).order_by('-event_date', '-id')[0]
    except IndexError:
        return None

现在我可以按 latest_event__whatever 过滤:

    return qs.filter(qobjs).order_by('-latest_event__event_date',
        '-latest_event__pk')
于 2015-09-07T01:12:49.017 回答