Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paginator for inline models in django admin

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')       
like image 328
Ulrich Dangel Avatar asked Jul 12 '11 13:07

Ulrich Dangel


People also ask

What is Paginator in Django?

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.

How does Django deal with pagination?

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.


2 Answers

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 
like image 104
tutuDajuju Avatar answered Sep 19 '22 23:09

tutuDajuju


For any version of Django, follow these steps:

  1. Visit this file : 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>&hellip;</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>&hellip;</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 
like image 31
DARK_C0D3R Avatar answered Sep 17 '22 23:09

DARK_C0D3R