jdv12
jdv12

Reputation: 171

dynamic pagination with django

Okay so this is first time using pagination with Django and I am trying to prevent it from reloading my view on each page turn.

I'm handling the pagination in the view like this:

page = request.GET.get('page', 1)
print page
paginator = Paginator(list(od.iteritems())[:24], 12)

try:
    data = paginator.page(page)
except PageNotAnInteger:
    data = paginator.page(1)
except EmptyPage:
    data = paginator.page(paginator.num_pages)

print data

save_query_form = SaveQueryForm(request.POST or None)
#if request.method == 'POST':
if save_query_form.is_valid():
    profile = save_query_form.save(commit=False)
    profile.user = request.user
    profile.save()

context = {
    "title":"Search",
    'data': data,#list(od.iteritems()),
    'tools': od_tools.iteritems(),
    'methods': od_methods.iteritems(),
    'data4': od_data.iteritems(),
    'search_phrase': " ".join(instanceValuesString),
    'json_dump': js_data,
    'form': save_query_form,
}
return render(request, 'results.html', context)

and the pagination is handled in the html:

{% if data.has_other_pages %}
    <div id='page-slide'>
        <ul class="pagination" start='$offset'>
            {% if data.has_previous %}
                <li><a href="?page={{ data.previous_page_number }}">&laquo;</a></li>
            {% else %}
                <li class="disabled"><span>&laquo;</span></li>
            {% endif %}
            {% for i in data.paginator.page_range %}
                {% if data.number == i %}
                    <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
                {% else %}
                    <li><a href="?page={{ i }}">{{ i }}</a></li>
                {% endif %}
            {% endfor %}
            {% if data.has_next %}
                <li><a href="?page={{ data.next_page_number }}">&raquo;</a></li>
            {% else %}
                <li class="disabled"><span>&raquo;</span></li>
            {% endif %}
        </ul>
    </div>
{% endif %} 

The issue that I am having is that whenever I switch to another page my entire view will run again and the data will does not reflect the original search query and instead defaults to an empty query.

I was wondering if there is a simple way to either handle pagination dynamically or prevent the page reload when toggling between pages?

Any help is appreciated, thanks.

Update Search Form:

<form action="{% url 'results-view' %}" method="POST" class="autocomplete-me ui-widget" id="myform" >
    {% csrf_token %}

    <div class="ui-widget" style="text-align:center;">
        <input type="text" id="id_q" name="q" placeholder="{{ search_phrase }}">
        <br></br>
        <div style="text-align:center;" id='adjust-button'>
            <input type='submit' class='btn btn-secondary btn-lg' id ='search-btn' value='Search'/>         
            <a class='btn btn-secondary btn-lg' id ='clear-btn' href="{% url 'inital' %}">Clear</a>
        </div>
    </div>
</form>

Upvotes: 1

Views: 4038

Answers (2)

souldeux
souldeux

Reputation: 3755

You noted in a comment that you get your search value with instanceValuesString = request.POST.get(u"q").encode('utf-8').strip(). As one commenter correctly pointed out, this means that when you click your "next page" links (making a GET request), your view doesn't receive the information it needs to return search results.

One way to fix this would be to get your instanceValuesString from a GET request instead of a POST request. For instance, perhaps your list view is at

http://example.com/StuffList

You could look for URLs that provide a search querystring:

http://example.com/StuffList?search=goodstuff

And then grab that in your view:

instanceValuesString = request.GET.get('search', None)
if instanceValuesString is not None:
    #you have detected a search query; filter results, process request, etc.

One side effect here is that the way you currently construct your next/previous page URLs will break. Consider the example search URL; your current template would construct a link for page 2 like so:

http://example.com/StuffList?search=goodstuff?page=2

This won't work; it should be &page=2. Fortunately there's an easy fix; check out the second answer to this question: Altering one query parameter in a url (Django). Using that url_replace instead of constructing those links with the basic url template tag will solve this part of the issue.

Upvotes: 2

anjaneyulubatta505
anjaneyulubatta505

Reputation: 11695

This is very much simplified with below package

http://django-simple-pagination.readthedocs.io/en/latest/

Upvotes: 0

Related Questions