Home > OS >  How to sorting with attrgetter from common foreign key attribute
How to sorting with attrgetter from common foreign key attribute

Time:07-23

doc_skai = DocSKAI.objects.all()
doc_added = DocAddedSKAI.objects.all()
result_list = sorted(chain(doc_skai, doc_added),key=attrgetter('???'), reverse=True)

both doc_skai and doc_added have foreign key with model Document, and Document model have a field of 'published_date'.

How can I sort the result list from the published_date of Document?

CodePudding user response:

You can work with a lambda-expression:

doc_skai = DocSKAI.objects.all()
doc_added = DocAddedSKAI.objects.all()
result_list = sorted(
    chain(doc_skai, doc_added),
    key=lambda x: x.document.published_date,
    reverse=True
)

But this will result in the so-called N 1 problem: for each DocSKAI and DocAddedSKAI, you will each time fetch the related document.

You can boost efficiency by selecting the related document with .select_related(..) [Django-doc]:

doc_skai = DocSKAI.objects.select_related('document')
doc_added = DocAddedSKAI.objects.select_related('document')
result_list = sorted(
    chain(doc_skai, doc_added),
    key=lambda x: x.document.published_date,
    reverse=True
)

This will load all the data of the relevant document, which might load a lot of data. We can also work with an annotation:

from django.db.models import F

doc_skai = DocSKAI.objects.annotate(published=F('document__published_date'))
doc_added = DocAddedSKAI.objects.annotate(published=F('document__published_date'))
result_list = sorted(
    chain(doc_skai, doc_added),
    key=attrgetter('published'),
    reverse=True
)

That being said, it is not clear to me why you have two different models named DocSKAI and DocAddedSKAI. It looks like it might be better to merge these into a single model with perhaps a boolean attribute added.

  • Related