Django Distinct and Foreign Key filtering Query

放肆的年华 提交于 2019-12-13 03:31:45

问题


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:


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.



来源:https://stackoverflow.com/questions/46367796/django-distinct-and-foreign-key-filtering-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!