Django Distinct and Foreign Key filtering Query

2019-08-17 20:03发布

I found questions about this problem but no working answer, so any help is appreciated :)

I want to display a list of the lastest Record made by each Client. Records is a model, which has Client as a field. Client is a ForeignKey for User.

For example

#Initially:

Client3 --- Record6
Client2 --- Record5
Client2 --- Record4
Client1 --- Record3
Client1 --- Record2
Client1 --- Record1

#Wanted: we only keep one Record per Client, the lastest one.

Client3 --- Record6
Client2 --- Record5
Client1 --- Record3

This is what I have tried:

def LastRecordPerClient(request):
    id_list = Record.objects.order_by('-date').values_list('client__id').distinct()
    records = Record.objects.filter(id__in=id_list)
    return (request, 'records/record_list.html', {"records": records})

This is what I get in my shell:

<QuerySet []>

Any idea?

EDIT : Solution Found

I found this solution :

class LastestListView(ListView):
    context_object_name = 'records'
    model = models.Record
    ordering = ['-date']
    paginate_by = 10

    def get_queryset(self):
        return self.model.objects.filter(pk__in=
        Record.objects.order_by('-date').values('client__id').annotate(
            max_id=Max('id')).values('max_id'))

1条回答
闹够了就滚
2楼-- · 2019-08-17 20:40

Why not Record.objects.filter(client_id=<client_id>).order_by('-date').last()?

I see, then the best way may be with a cached_property

models.py:

class Client(models.model):
    name = models.CharField(...)
    ....
    @cached_property
    def latest_record = Record.objects.filter(client=self).order_by('-date').last()

Then in your view:

clients = Client.objects.all().prefetch_related('record')

and

for client in clients:
   print(client.name)
   print(client.latest_record.date)

This would give you the output you asked for in the question.

查看更多
登录 后发表回答