src/jocondelab/utils.py
author veltr
Fri, 27 Sep 2013 16:38:05 +0200
changeset 125 5f7f0056de36
parent 48 f4fadc1b9d70
child 232 e031590c848d
permissions -rw-r--r--
language handling changes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
# -*- coding: utf-8 -*-
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
'''
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
Created on Jun 16, 2013
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
@author: ymh
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
'''
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
from django.conf import settings
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
from django.core.paginator import Paginator, Page, PageNotAnInteger, EmptyPage
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
import logging
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
logger = logging.getLogger(__name__)
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
class JocondePaginator(Paginator):
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
    def validate_number(self, number):
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
        "Validates the given 1-based page number."
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
        try:
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
            number = int(number)
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
        except (TypeError, ValueError):
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
            raise PageNotAnInteger('That page number is not an integer')
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
        if number < 1:
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
            return 1
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
        if number > self.num_pages:
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
            if number == 1 and self.allow_empty_first_page:
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
                return 1
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
            elif self.num_pages > 0: 
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
                return self.num_pages
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
            else:
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
                raise EmptyPage('That page contains no results')
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
        return number
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
    
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
    def page(self, number):        
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
        page = super(JocondePaginator, self).page(number)
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
        return JocondePage(page.object_list, page.number, self)
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
class JocondePage(Page):
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
    
20
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    42
    visible_range = getattr(settings, 'PAGINATOR_VISIBLE_RANGE', 5)
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    43
    start_range = getattr(settings, 'PAGINATOR_START_RANGE', visible_range/2)
48
f4fadc1b9d70 cache the nb_notice query to improve perf.
ymh <ymh.work@gmail.com>
parents: 43
diff changeset
    44
        
5
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
    def __get_start_range(self):
20
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    46
        return max(1,self.number-self.visible_range/2)
5
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
    
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
    def __get_end_range(self):
20
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    49
        return min(self.paginator.num_pages, self.number+self.visible_range/2) + 1
5
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
    
20
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    51
    def visible_page_range(self):        
5
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
        start = self.__get_start_range()
580fd386c4b9 Improve design, add context
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
        end = self.__get_end_range()
20
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    54
                
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    55
        ranges = set(range(1,self.start_range+1)) | set(range(start , end)) | set(range(self.paginator.num_pages - self.start_range +1, self.paginator.num_pages+1))         
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    56
        prev = None
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    57
        res = []
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    58
        for i in sorted(ranges):
27
d5f4dde387a9 - Correct pagination on page load
ymh <ymh.work@gmail.com>
parents: 20
diff changeset
    59
            if 1 <= i <= self.paginator.num_pages:
d5f4dde387a9 - Correct pagination on page load
ymh <ymh.work@gmail.com>
parents: 20
diff changeset
    60
                if prev and i-prev > 1:
d5f4dde387a9 - Correct pagination on page load
ymh <ymh.work@gmail.com>
parents: 20
diff changeset
    61
                    res.append(0)
d5f4dde387a9 - Correct pagination on page load
ymh <ymh.work@gmail.com>
parents: 20
diff changeset
    62
                res.append(i)
d5f4dde387a9 - Correct pagination on page load
ymh <ymh.work@gmail.com>
parents: 20
diff changeset
    63
                prev = i
20
ec738ea574a7 improve pagination add total nb to request
ymh <ymh.work@gmail.com>
parents: 5
diff changeset
    64
        return res