Cyril
Cyril

Reputation: 43

Paginator and POST request for SearchForm

I've an issue with Paginator in Django, I tried several solution but none is working as I want...

Views

def order_list(request)
    form = SearchOrderForm()
    if 'search-order-post' in request.session:
        form = SearchOrderForm(request.session['search-order-post'])
        is_cookie_set = 1

    if request.method == 'POST':
        form = SearchOrderForm(request.POST)
        request.session['search-order-post'] = request.POST
        is_cookie_set = 1

    if is_cookie_set == 1:
        if form.is_valid():
            statut = form.cleaned_data['statut']
            clients = form.cleaned_data['clients']
    [...]
    paginator = Paginator(orders, 50)
    page = request.GET.get('page')

    try:
        orders_page = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        orders_page = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        orders_page = paginator.page(paginator.num_pages)

context = {'clients': clients,
               'orders': orders_page,
               'orders_list': orders,
               'paginate': True,
               'form': form,
               }
    return render(request, 'order/list.html', context)

When I use Paginator in GET, to go to page 2 for exemple ... I lost all my query :( Is there any other way ? form.is_valid() return False when i change page

Upvotes: 0

Views: 145

Answers (2)

Cyril
Cyril

Reputation: 43

Solution with GET request :

TEMPLATE

{% if paginate %}
<div class="clearfix"></div>
<nav aria-label="...">
<ul class="pagination justify-content-center">
    {% if orders.has_previous %}
        {% if query_string %}
        <li class="page-item"><a class="page-link" href="?{{ query_string }}&page={{ orders.previous_page_number }}{{ getvars }}"><<</a></li>
        {% else %}
        <li class="page-item"><a class="page-link" href="?page={{ orders.previous_page_number }}{{ getvars }}"><<</a></li>
        {% endif %}
    {% else %}
        <li class="page-item disabled"><a class="page-link" href="#"><<</a></li>
    {% endif %}
    {% if orders.number|add:'-4' > 1 %}
        {% if query_string %}
        <li class="page-item"><a class="page-link" href="?{{ query_string }}&page={{ orders.number|add:'-5' }}{{ getvars }}">...</a></li>
        {% else %}
        <li class="page-item"><a class="page-link" href="?page={{ orders.number|add:'-5' }}{{ getvars }}">...</a></li>
        {% endif %}
    {% endif %}
    {% for i in orders.paginator.page_range %}
        {% if orders.number == i %}
            <li class="page-item active"><span class="page-link" href="#">{{ i }}</span></li>
        {% elif i > orders.number|add:'-5' and i < orders.number|add:'10' %}
            {% if query_string %}
            <li class="page-item"><a class="page-link" href="?{{ query_string }}&page={{ i }}{{ getvars }}">{{ i }}</a></li>
            {% else %}
            <li class="page-item"><a class="page-link" href="?page={{ i }}{{ getvars }}">{{ i }}</a></li>
            {% endif %}
        {% endif %}
    {% endfor %}
    <!-- <span class="current">{{ commandes.number }} / {{ commandes.paginator.num_pages }}</span>-->
    {% if orders.has_next %}
        {% if query_string %}
        <li class="page-item"><a class="page-link" href="?{{ query_string }}&page={{ orders.next_page_number }}{{ getvars }}">>></a></li>
        {% else %}
        <li class="page-item"><a class="page-link" href="?page={{ orders.next_page_number }}{{ getvars }}">>></a></li>
        {% endif %}
    {% endif %}
    {% else %}
        <li class="page-item disabled"><a class="page-link" href="#">>></a></li>
    {% endif %}
</ul>
</nav>
{% endif %}

VIEWS

paginator = Paginator(orders, 50)
    get_data = request.GET.copy()
    page = request.GET.get('page')

    try:
        orders_page = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        orders_page = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        orders_page = paginator.page(paginator.num_pages)

    context = {'orders': orders_page,
               'paginate': True,
               'form': form,
               'formAction': formAction,
               'query_string': get_data.urlencode(),
               }
    return render(request, 'order/list.html', context)

Maybe there is a better way ... but actually it's works ;) I know it's possible with POST and session or cookie ... but I give up for the moment ... Thanks all for. your help

Upvotes: 0

Iain Shelvington
Iain Shelvington

Reputation: 32244

If you change to using GET, you will need to be able to generate the pagination links with the form data and the correct page number. You can use QueryDict.urlencode() to generate a querystring from GET data, if you first pop the current page number you can then provide this manually

def order_list(request):

    ...

    get_data = request.GET.copy()
    page = get_data.pop('page', None)

    ...

    context = {
        ...,
        'query_string': get_data.urlencode(),
     }
    return render(request, 'order/list.html', context)

Template

    <a href="?{% if query_string %}{{ query_string }}&{% endif %}page={{ page_obj.next_page_number }}">next</a>

Upvotes: 1

Related Questions