class PaginationMixin(object): """ Get the paginate_by value from either (in order of priority): - the querystring - the session - the User's profile in the database - the default value Limit the chosen paginate_by value to avoid abuse (for example, setting it to 0 makes Django return all the items). Save the value in the session so that the User doesn't have to specity it. """ DEFAULT_PAGE_SIZE = 10 MIN_PAGE_SIZE = 1 MAX_PAGE_SIZE = 50 def get_paginate_by(self, queryset): # Get the page_size value page_size = (int(self.request.GET.get('page_size', 0)) or self.request.session.get('page_size') or self.request.user.profile.page_size or self.DEFAULT_PAGE_SIZE) # Limit the page_size to lie between the set range if page_size < self.MIN_PAGE_SIZE or page_size > self.MAX_PAGE_SIZE: page_size = self.DEFAULT_PAGE_SIZE # Save the page_size in the session self.request.session['page_size'] = page_size # Save the page_size in the User's Profile model, but only if it changed. if page_size != self.request.user.profile.page_size: self.request.user.profile.page_size = page_size self.request.user.profile.save() # Return the page_size return page_size