Darwin Tech
Darwin Tech

Reputation: 18919

Django multiple querysets paginated as one

Hi I am constructing a search results page which combine multiple query sets from multiple databases which I would like to paginate as one set.

in my view I have:

def combined_search(request):
    ...
    first_query_set = Mytable_db1.objects.select_related().filter(q)
    first_count = first_query_set.count

    second_query_set = Mytable_db2.objects.select_related().filter(q)
    second_count = second_query_set.count
    # combine querysets
    combined_query_set = list(chain(first_query_set, second_query_set))

    # create a new paginator instance with items-per-page
    paginator = Paginator(combined_query_set, 5)
    # get the page number from a get param if param is blank then set page to 1 
    page = int(request.GET.get('page', '1')) 
    # grab the current page from the paginator...  
    items = paginator.page(page)
    ...

Then in my template I want something like:

<h1>{{ first_count }} results in mydb1:</h1>
{% for x in first_query_set %}
     <p>{{ x.field }}</p>
{% endfor %}


<h1>{{ second_count }} results in mydb2:</h1>
{% for y in second_query_set %}
     <p>{{ y.field }}</p>
{% endfor %}

The problem is that I want to paginate both sets as if they were one but including the titles. So if there is only 2 results for the first set, and 18 for the second, the first set (including title) just appear on the first page and I have 3 further pages for the second set.

Upvotes: 3

Views: 2183

Answers (1)

Chris Lacasse
Chris Lacasse

Reputation: 1562

You'll want to paginate the querysets separately but then map the page number from the request to the appropriate paginator.

Something like this:

page = int(request.GET.get('page', '1'))
first_set_page_count = math.ceil(first_count / 5)
if page > first_set_page_count:
    page = page - first_set_page_count
    items = second_paginator.page(page)
else:
    items = first_paginator.page(page)

Upvotes: 2

Related Questions