I have this simple django model consisting of an sensor and values for the specific sensor. The number of values per Pyranometer is high (>30k). Is it somehow possible to paginate PyranometerValues
by a specific day or generell apply a paginator to the admin inline view?
class Pyranometer(models.Model): name = models.CharField(max_length=75) class PyranometerValues(models.Model): timestamp = models.DateTimeField() value = models.DecimalField(max_digits=10,decimal_places=6) sensor = models.ForeignKey('Pyranometer')
Django provides a few classes that help you manage paginated data – that is, data that's split across several pages, with “Previous/Next” links. These classes live in django/core/paginator.py. For examples, see the Pagination topic guide.
Note that you can give Paginator a list/tuple, a Django QuerySet , or any other object with a count() or __len__() method. When determining the number of objects contained in the passed object, Paginator will first try calling count() , then fallback to using len() if the passed object has no count() method.
If anyone requires this, I found this nice (though described as "quite hacky") implementation of a pagination TabularInline
subclass in this comment of a django-suit issue.
For Django 1.6 it requires a template change and subclassing this PaginationInline
class:
from django.contrib import admin from django.contrib.admin.views.main import ChangeList from django.core.paginator import EmptyPage, InvalidPage, Paginator class InlineChangeList(object): can_show_all = True multi_page = True get_query_string = ChangeList.__dict__['get_query_string'] def __init__(self, request, page_num, paginator): self.show_all = 'all' in request.GET self.page_num = page_num self.paginator = paginator self.result_count = paginator.count self.params = dict(request.GET.items()) class PaginationInline(admin.TabularInline): template = 'admin/edit_inline/tabular_paginated.html' per_page = 20 def get_formset(self, request, obj=None, **kwargs): formset_class = super(PaginationInline, self).get_formset( request, obj, **kwargs) class PaginationFormSet(formset_class): def __init__(self, *args, **kwargs): super(PaginationFormSet, self).__init__(*args, **kwargs) qs = self.queryset paginator = Paginator(qs, self.per_page) try: page_num = int(request.GET.get('p', '0')) except ValueError: page_num = 0 try: page = paginator.page(page_num + 1) except (EmptyPage, InvalidPage): page = paginator.page(paginator.num_pages) self.cl = InlineChangeList(request, page_num, paginator) self.paginator = paginator if self.cl.show_all: self._queryset = qs else: self._queryset = page.object_list PaginationFormSet.per_page = self.per_page return PaginationFormSet
For any version of Django, follow these steps:
python3.7/site-packages/django/contrib/admin/templates/admin/edit_inline/tabular.html
make a copy of it in your app/templates/admin/edit_inline/anyname.html
between </table>
and </fieldset>
tag add in anyname.html:
<style> .dark { /*background-color: #417690;*/ background-color: #FFFFFF; border: none; color: #666; padding: 5px 10px; text-align: center; text-decoration: none; display: inline-block; font-size: 12px; margin: 4px 2px; cursor: pointer; } .light { background-color: #008CBA; border: none; color: white; padding: 5px 10px; text-align: center; text-decoration: none; display: inline-block; font-size: 12px; margin: 4px 2px; cursor: pointer; } </style> <div> {% with inline_admin_formset.formset.page as page_obj %} <p class="paginator"> {% if page_obj.previous_page_number > 1 %} <a href="?page={{ page_obj.previous_page_number|add:'-1' }}">{% trans 'previous' %}</a> {% endif %} {% if page_obj.number|add:"-5" > 0 %} <a href="?page=0">1</a> {% endif %} {% if page_obj.number|add:"-5" > 1 %} <span>…</span> {% endif %} {% for page_num in page_obj.paginator.page_range %} {% if page_obj.number == page_num %} <span class="dark">{{ page_num|add:"-1" }}</span> {% else %} {% if page_num > page_obj.number|add:"-5" and page_num < page_obj.number|add:"5" %} <a class="light" style="color:white" href="?page={{ page_num|add:'-1' }}">{{ page_num|add:"-1" }}</a> {% endif %} {% endif %} {% endfor %} {% if page_obj.number|add:"5" < page_obj.paginator.num_pages %} <span>…</span> {% endif %} {% if page_obj.number|add:"4" < page_obj.paginator.num_pages %} <a href="?page={{ page_obj.paginator.num_pages }}">{{ page_obj.paginator.num_pages }}</a> {% endif %} {% if page_obj.next_page_number < page_obj.paginator.num_pages|add:'1' %} <a href="?page={{ page_obj.next_page_number|add:'-1' }}">{% trans 'next' %}</a> {% endif %} <span class='dark'>{{ page_obj.paginator.count }} Queries</span> </p> {% endwith %} </div>
2.Go to your admin.py file:
from django.contrib.admin.views.main import ChangeList from django.core.paginator import EmptyPage, InvalidPage, Paginator class InlineChangeList(object): can_show_all = True multi_page = True get_query_string = ChangeList.__dict__['get_query_string'] def __init__(self, request, page_num, paginator): self.show_all = 'all' in request.GET self.page_num = page_num self.paginator = paginator self.result_count = paginator.count self.params = dict(request.GET.items()) class MyInline(admin.TabularInline): per_page = 10 template = 'admin/edit_inline/anyname.html' model = Mymodel extra = 0 can_delete = False def get_formset(self, request, obj=None, **kwargs): formset_class = super(MyInline, self).get_formset( request, obj, **kwargs) class PaginationFormSet(formset_class): def __init__(self, *args, **kwargs): super(PaginationFormSet, self).__init__(*args, **kwargs) qs = self.queryset paginator = Paginator(qs, self.per_page) try: page_num = int(request.GET.get('page', ['0'])[0]) except ValueError: page_num = 0 try: page = paginator.page(page_num + 1) except (EmptyPage, InvalidPage): page = paginator.page(paginator.num_pages) self.page = page self.cl = InlineChangeList(request, page_num, paginator) self.paginator = paginator if self.cl.show_all: self._queryset = qs else: self._queryset = page.object_list PaginationFormSet.per_page = self.per_page return PaginationFormSet
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With