Django使用order_by查询,不同并限制Postgresql

Cha*_*thk 8 django postgresql django-queryset

我有以下内容:

class Product(models.Model):
    name = models.CharField(max_length=255)

class Action(models.Model):
    product = models.ForeignKey(Product)
    created_at = models.DateTimeField(auto_now_add=True)
Run Code Online (Sandbox Code Playgroud)

我想检索created_at DESC使用不同产品订购的10个最新动作.

以下是接近结果,但仍然错过了顺序:

Action.objects.all().order_by('product_id').distinct('product_id')[:10]
Run Code Online (Sandbox Code Playgroud)

Ros*_*ote 15

您的解决方案似乎正在尝试做太多.它还将导致2个单独的SQL查询.这可以正常工作,只有一个查询:

action_ids = Action.objects.order_by('product_id', '-created_at')\
    .distinct('product_id').values_list('id', flat=True)

result = Action.objects.filter(id__in=action_ids)\
    .order_by('-created_at')[:10]
Run Code Online (Sandbox Code Playgroud)


Cha*_*thk 5

编辑:此解决方案有效,但罗斯·洛特的清洁

这是我最终使用Django Aggregation完成的方式

from django.db.models import Max

actions_id = Action.objects.all().values('product_id') \
    .annotate(action_id=Max('id')) \
    .order_by('-action_id')[:10] \
    .values_list('action_id', flat=True)

result = Action.objects.filter(id__in=actions_id).order_by('-created_at')
Run Code Online (Sandbox Code Playgroud)

通过设置,values('product_id')我们对product_id进行分组

通过,annotate()我们只能在或中使用的字段上使用order_by。由于对于每个操作,created_at字段都会自动设置为now,因此对created_at的排序与对id的排序相同,使用正确的方法。values()annotate()annotate(action_id=Max('id')).order_by('-action_id')

好的,我们只需要对查询进行切片 [:10]

希望这可以帮助。