How to combine two or more querysets in a Django view?

后端 未结 13 2625
猫巷女王i
猫巷女王i 2020-11-21 22:40

I am trying to build the search for a Django site I am building, and in that search, I am searching in 3 different models. And to get pagination on the search result list, I

13条回答
  •  滥情空心
    2020-11-21 23:20

    Concatenating the querysets into a list is the simplest approach. If the database will be hit for all querysets anyway (e.g. because the result needs to be sorted), this won't add further cost.

    from itertools import chain
    result_list = list(chain(page_list, article_list, post_list))
    

    Using itertools.chain is faster than looping each list and appending elements one by one, since itertools is implemented in C. It also consumes less memory than converting each queryset into a list before concatenating.

    Now it's possible to sort the resulting list e.g. by date (as requested in hasen j's comment to another answer). The sorted() function conveniently accepts a generator and returns a list:

    result_list = sorted(
        chain(page_list, article_list, post_list),
        key=lambda instance: instance.date_created)
    

    If you're using Python 2.4 or later, you can use attrgetter instead of a lambda. I remember reading about it being faster, but I didn't see a noticeable speed difference for a million item list.

    from operator import attrgetter
    result_list = sorted(
        chain(page_list, article_list, post_list),
        key=attrgetter('date_created'))
    

提交回复
热议问题