db_table = app_label + '_' + 'profiles'
verbose_name = _('profile')
-import string\r
-from django.core.paginator import InvalidPage, EmptyPage\r
-\r
-class NamePaginator(object):\r
- """Pagination for string-based objects"""\r
- \r
- def __init__(self, object_list, on=None, per_page=25):\r
- self.object_list = object_list\r
- self.count = len(object_list)\r
- self.pages = []\r
- \r
- # chunk up the objects so we don't need to iterate over the whole list for each letter\r
- chunks = {}\r
- \r
- for obj in self.object_list:\r
- if on: obj_str = str(getattr(obj, on))\r
- else: obj_str = str(obj)\r
- \r
- letter = str.upper(obj_str[0])\r
- \r
- if letter not in chunks: chunks[letter] = []\r
- \r
- chunks[letter].append(obj)\r
- \r
- # the process for assigning objects to each page\r
- current_page = NamePage(self)\r
- \r
- for letter in string.ascii_uppercase:\r
- if letter not in chunks: \r
- current_page.add([], letter)\r
- continue\r
- \r
- sub_list = chunks[letter] # the items in object_list starting with this letter\r
- \r
- new_page_count = len(sub_list) + current_page.count\r
- # first, check to see if sub_list will fit or it needs to go onto a new page.\r
- # if assigning this list will cause the page to overflow...\r
- # and an underflow is closer to per_page than an overflow...\r
- # and the page isn't empty (which means len(sub_list) > per_page)...\r
- if new_page_count > per_page and \\r
- abs(per_page - current_page.count) < abs(per_page - new_page_count) and \\r
- current_page.count > 0:\r
- # make a new page\r
- self.pages.append(current_page)\r
- current_page = NamePage(self)\r
- \r
- current_page.add(sub_list, letter)\r
- \r
- # if we finished the for loop with a page that isn't empty, add it\r
- if current_page.count > 0: self.pages.append(current_page)\r
- \r
- def page(self, num):\r
- """Returns a Page object for the given 1-based page number."""\r
- if len(self.pages) == 0:\r
- return None\r
- elif num > 0 and num <= len(self.pages):\r
- return self.pages[num-1]\r
- else:\r
- raise InvalidPage\r
- \r
- @property\r
- def num_pages(self):\r
- """Returns the total number of pages"""\r
- return len(self.pages)\r
-\r
-class NamePage(object):\r
- def __init__(self, paginator):\r
- self.paginator = paginator\r
- self.object_list = []\r
- self.letters = []\r
- \r
- @property\r
- def count(self):\r
- return len(self.object_list)\r
- \r
- @property\r
- def start_letter(self):\r
- if len(self.letters) > 0: \r
- self.letters.sort(key=str.upper)\r
- return self.letters[0]\r
- else: return None\r
- \r
- @property\r
- def end_letter(self):\r
- if len(self.letters) > 0: \r
- self.letters.sort(key=str.upper)\r
- return self.letters[-1]\r
- else: return None\r
- \r
- @property\r
- def number(self):\r
- return self.paginator.pages.index(self) + 1\r
- \r
- def add(self, new_list, letter=None):\r
- if len(new_list) > 0: self.object_list = self.object_list + new_list\r
- if letter: self.letters.append(letter)\r
- \r
- def __repr__(self):\r
- if self.start_letter == self.end_letter:\r
- return self.start_letter\r
- else:\r
- return '%c-%c' % (self.start_letter, self.end_letter)
\ No newline at end of file