-1

hello i want add Paginator in search result page how to do this ?

my code :

view.py :

def search(request):
if request.method == 'GET':
    query= request.GET.get('q')
    submitbutton= request.GET.get('submit')

    if query is not None:

        home_database= Homepage.objects.filter(Q(name__icontains=query) | Q(app_contect__icontains=query) | Q(page_url__icontains=query) | Q(app_image__icontains=query))
        pcprograms_database= PCprogram.objects.filter(Q(name__icontains=query) | Q(app_contect__icontains=query) | Q(page_url__icontains=query) | Q(app_image__icontains=query))
        androidapk_database= AndroidApks.objects.filter(Q(name__icontains=query) | Q(app_contect__icontains=query) | Q(page_url__icontains=query) | Q(app_image__icontains=query))
        androidgames_database= AndroidGames.objects.filter(Q(name__icontains=query) | Q(app_contect__icontains=query) | Q(page_url__icontains=query) | Q(app_image__icontains=query))
        antiruvs_database= Antivirus.objects.filter(Q(name__icontains=query) | Q(app_contect__icontains=query) | Q(page_url__icontains=query) | Q(app_image__icontains=query))
        systems_database= OpratingSystems.objects.filter(Q(name__icontains=query) | Q(app_contect__icontains=query) | Q(page_url__icontains=query) | Q(app_image__icontains=query))
        pcgames_database= PCgames.objects.filter(Q(name__icontains=query) | Q(app_contect__icontains=query) | Q(page_url__icontains=query) | Q(app_image__icontains=query))

        results= sorted(chain(home_database,pcprograms_database,androidapk_database,androidgames_database,antiruvs_database,systems_database,pcgames_database),key=attrgetter('name'))

        paginator = Paginator(results, 2) # Show 25 rows per page
        page = request.GET.get('page')
        results = paginator.get_page(page)

        context={'results': results,
                 'submitbutton': submitbutton}

        return render(request, 'html_file/enterface.html', context)

    else:
        return render(request, 'html_file/enterface.html')

else:
    return render(request, 'html_file/enterface.html')

html page :

     {% if submitbutton == 'Search' and request.GET.q != '' %}
 {% if results %}
 <h1> <small> Results for <b><i style="color:#337ab7">{{ request.GET.q }}</i></b></small> : </h1>
 <br/><br/>

 {% for result in results %}
 <label id="label_main_app"> <img style="margin-top:.3%;margin-left:.3%" id="img_main_app_first_screen" src="{{result.app_image.url}}" alt="no image found !" height="160" width="165" > {{result.name}} <br><br> <p id="p_size_first_page"> {{result.app_contect}} <br> <br> <a href="{{ result.page_url }}" type="button" class="btn btn-primary"><big> See More & Download </big>  </a> </p>
  </label>

 {% endfor %}

 <!–– here for moving to make new pages in search if nedded  ––>
 {% if results.has_other_pages %}
   <ul class="pagination">
     {% if results.has_previous %}
       <li><a href="?q={{ request.GET.q }}&submit=Search/search-page={{ results.previous_page_number }}">&laquo;</a></li>
     {% else %}
       <li class="disabled"><span>&laquo;</span></li>
     {% endif %}
     {% for i in results.paginator.page_range %}
       {% if results.number == i %}
         <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
       {% else %}
         <li><a href="?q={{ request.GET.q }}&submit=Search/search-page={{ i }}">{{ i }}</a></li>
       {% endif %}
     {% endfor %}
     {% if results.has_next %}
       <li><a href="?q={{ request.GET.q }}&submit=Search/search-page={{ results.next_page_number }}">&raquo;</a></li>
     {% else %}
       <li class="disabled"><span>&raquo;</span></li>
     {% endif %}
   </ul>
 {% endif %}


 {% endif %}

 {% endif %}

i have added Paginator to search result in django okay ? and i put show 2 item in page and i have 8 item in page

but when i do a search in website it's show 2 item okay

and show to me 4 pages i can move to it but when i press on page 2 or 3 or 4 it's doesn't show anything why ?

  • Django provides the `Paginator` class to perform pagination, I have answered a similar question to this here: (https://stackoverflow.com/a/58300833/9197808) You can also check the docs here: (https://docs.djangoproject.com/en/dev/topics/pagination/#paginator-objects) – Sammy J Oct 30 '19 at 16:38
  • i read the answer but it's doesn't help me , i don't know why – Kutaiba H Momani Oct 31 '19 at 17:41
  • can you write the code what i need to add in my code for active pagination please ? – Kutaiba H Momani Oct 31 '19 at 18:15
  • check out the answer below, I hope it helps, else feel free to ask your doubts. – Sammy J Oct 31 '19 at 18:51
  • i have tried your answer and this what happened i have added Paginator to search result in django okay ? and i put show 2 item in page and i have 8 item in page but when i do a search in website it's show 2 item okay and show to me 4 pages i can move to it but when i press on page 2 or 3 or 4 it's doesn't show anything why ? – Kutaiba H Momani Nov 01 '19 at 07:52
  • Try removing the else part in HTML and let's see what happens, please edit the question also to include what you have done, don't overwrite the existing question, just add your edited question below it – Sammy J Nov 01 '19 at 08:22
  • i tried this and removed else part but it's same nothing change , and this is my new code i have edited the question – Kutaiba H Momani Nov 01 '19 at 08:38
  • i don't know where is the error – Kutaiba H Momani Nov 01 '19 at 08:39
  • give the href in paginarion as only `href="?search-page={{ results.next_page_number }}` like I gave `page=` in my example? – Sammy J Nov 01 '19 at 15:41
  • i already tried this and also dosen't work ,, i heard something if i'm using ' chain ' (multi models ) in results i can' t use paginarion ,,, i don't know if this correct ? – Kutaiba H Momani Nov 01 '19 at 16:00
  • I guess `chain` is not the problem but `list` you must use `sorted` instead, check the answer I have edited now – Sammy J Nov 01 '19 at 16:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/201729/discussion-between-kutaiba-h-momani-and-sammy-j). – Kutaiba H Momani Nov 01 '19 at 16:46
  • yes i see the edit and try it but nothing changed – Kutaiba H Momani Nov 01 '19 at 16:50
  • please join the chat window here : (https://chat.stackoverflow.com/rooms/201729/discussion-between-kutaiba-h-momani-and-sammy-j) – Sammy J Nov 01 '19 at 16:52
  • i'm in chat please check it – Kutaiba H Momani Nov 01 '19 at 17:00

1 Answers1

0

Django provides the Paginator class to perform pagination, check the docs here: Paginator objects.

So in your views.py after

results= list(chain(home_database,pcprograms_database,androidapk_database,androidgames_database,antiruvs_database,systems_database,pcgames_database))

you can write

paginator = Paginator(results, 25) # Show 25 rows per page
page = request.GET.get('page')
results = paginator.get_page(page)
context={'results': results,
             'submitbutton': submitbutton}
return render(request, 'html_file/enterface.html', context)

The next step in your HTML file:

{% if submitbutton == 'Search' and request.GET.q != '' %}
 {% if results %}
 <h1> <small> Results for {{ request.GET.q }} : </small></h1>
 <br/><br/>

 {% for result in results %}
 <label id="label_main_app"> <img style="margin-top:.3%;margin-left:.3%"  id="img_main_app_first_screen" src="{{result.app_image.url}}" alt="no image found !" height="160" width="165" > {{result.name}} <br><br> <p id="p_size_first_page"> {{result.app_contect}} <br> <br> <a href="{{ result.page_url }}" type="button" class="btn btn-primary"><big> See More & Download </big>  </a> </p>
  </label>
 {% endfor %}

 {% if results %}
 <div class="pagination">
  <span class="step-links">
    {% if results.has_previous %}
        <a href="?page=1">&laquo; first</a>
        <a href="?page={{ results.previous_page_number }}">previous</a>
    {% endif %}

    <span class="current">
        Page {{ results.number }} of {{ results.paginator.num_pages }}.
    </span>

    {% if results.has_next %}
        <a href="?page={{ results.next_page_number }}">next</a>
        <a href="?page={{ results.paginator.num_pages }}">last &raquo;</a>
    {% endif %}
    </span>
  </div>
  {% endif %}
 {% else %}
 <h3> No results for this search </h3>
 {% endif %}
 {% endif %}

Since combining multiple querysets causes issues with pagination, I guess you must also sort them by a common key, so based on this answerSO Answer to a similar issue, you might have to sort all these query. So instead of giving list(chain( try the below code:

from operator import attrgetter
results = sorted(
    chain(home_database,pcprograms_database,androidapk_database, ..etc),
    key=attrgetter('common_key'))

You can decide on the common_key, maybe the field name in your case?

Sammy J
  • 1,048
  • 10
  • 28
  • okay , i did this and i have now one error the error is when user press on next and go to next page , there are no result appear in page 2 or 3 etc ... ** i have added 8 apps with same names so when i search about it i already see 6 in one page but when i press on next no apps appear and the url change to 172.1.1.1/search/?page=2 – Kutaiba H Momani Oct 31 '19 at 19:16
  • okay ,, i tried again but it's same thing nothing change it's keep doesn't show rest results i will update my question ,, check out the update please and thanks for your time – Kutaiba H Momani Nov 01 '19 at 16:48