5

I would like to implement custom pagination for my admin panel.

My url looks like the following: http://localhost:8000/admin/items/?group_id=20

On this URL I do some work to filter the results using the parameter group_id (by overriding get_changelist method).

The page results are corrects, the problem is my pagination ending up like this http://localhost:8000/admin/items/?p=1 whereas I would like the URL to be http://localhost:8000/admin/items/?group_id=20&p=1 and keep the parameter.

Basically I want the same result as How to paginate Django with other get variables? but using Django admin.

How can I keep the parameter along with the pagination?

I've tried overriding pagination.html file but without any success.

Thank you.

Edit

I've tried overriding pagination.html but request.GET.items is still empty (even if my settings file is well configured)

{% load admin_list %}
{% load i18n %}
{% load content_extras %}
<p class="paginator">
{% if pagination_required %}
    {% for i in page_range %}
        <a href="?p={{ i }}{% for key, value in request.GET.items %}{% if key != 'p' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">{{ i }}</a>
    {% endfor %}
{% endif %}
{{ cl.result_count }} {% if cl.result_count == 1 %}{{ cl.opts.verbose_name }}{% else %}{{ cl.opts.verbose_name_plural }}{% endif %}
{% if show_all_url %}<a href="{{ show_all_url }}" class="showall">{% trans 'Show all' %}</a>{% endif %}
{% if cl.formset and cl.result_count %}<input type="submit" name="_save" class="default" value="{% trans 'Save' %}">{% endif %}
</p>
Yogi Bear
  • 603
  • 8
  • 22

2 Answers2

3

FOUND A SOLUTION:

1/ Override changelist_view on admin.py and pass the extra data

def changelist_view(self, request, extra_context=""):
    response = super(ItemAdmin, self).changelist_view(request, extra_context)

    group_id = request.GET.get('group_id', None)

    if group_id:
        extra_context = {
            'group_id': group_id,
        }
        response.context_data.update(extra_context)

    return TemplateResponse(request, "admin/changelist.html", response.context_data)

2/ Create changelist.html file based on django admin template (copy/paste)

Add {% load content_extras %} at the top of the file (line 3)

Change line {% block pagination %}{% pagination cl %}{% endblock %} with {% block pagination %}{% custom_pagination cl %}{% endblock %}

3/ Create content_extras.py under templatetags folder and write custom_pagination function

from django import template
from django.contrib.admin.templatetags import admin_list

register = template.Library()


@register.inclusion_tag('admin/pagination.html', takes_context=True)
def custom_pagination(context, cl):
    pagination = admin_list.pagination(cl)
    if 'group_id' in context:
        params = (('group_id', context['group_id']),)
        pagination['params'] = params
    return pagination

4/ Create pagination.html (same location as changelist.html)

{% load admin_list %}
{% load i18n %}
{% load content_extras %}
<p class="paginator">
{% if pagination_required %}
    {% for i in page_range %}
        <a href="?p={{ i }}{% for key, value in params %}{% if key != 'p' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">{{ i }}</a>
    {% endfor %}
{% endif %}
{{ cl.result_count }} {% if cl.result_count == 1 %}{{ cl.opts.verbose_name }}{% else %}{{ cl.opts.verbose_name_plural }}{% endif %}
{% if show_all_url %}<a href="{{ show_all_url }}" class="showall">{% trans 'Show all' %}</a>{% endif %}
{% if cl.formset and cl.result_count %}<input type="submit" name="_save" class="default" value="{% trans 'Save' %}">{% endif %}
</p>
Yogi Bear
  • 603
  • 8
  • 22
0

If you activated django.template.context_processors.request in your settings, you can access parameters from your request directly from your template.

And then you can access the parameters in your templates directly. Something like:

href="?page={{ data.next_page_number }}{% for key, value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}"

Research (context_processors.request was moved from django.core to django.templates some time ago)

crimsonpython24
  • 2,223
  • 2
  • 11
  • 27