Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paginate Class-based View in Django

I am trying to paginate my class-based view. Here is how my view looks:

class IssuesByTitleView(ListView):
    context_object_name = "issue_list"

    def issues(request):
        issue_list = Issue.objects.all()
        ###### Commented out does not work ######
        # paginator = Paginator(issue_list, 24)
        # try:
        #    page = int(request.GET.get('page', '1'))
        # except ValueError:
        #   page = 1
        # try:
        #    issues = paginator.page(page)
        # except (EmptyPage, InvalidPage):
        #    issues = paginator.page(paginator.num_pages)

    def get_queryset(self):
        self.title = get_object_or_404(Title, slug=self.kwargs['title_slug'])
        return Issue.objects.filter(title=self.title).order_by('-number')
    def get_context_data(self, **kwargs):
        context = super(IssuesByTitleView, self).get_context_data(**kwargs)
        context['title'] = self.title
        return context

Here is a sample of my models for some context:

class Title(models.Model):
    CATEGORY_CHOICES = (
    ('Ongoing', 'Ongoing'),    
    ('Ongoing - Canceled', 'Ongoing - Canceled'),
    ('Limited Series', 'Limited Series'),
    ('One-shot', 'One-shot'),
    ('Other', 'Other'),
    )    
    title = models.CharField(max_length=64)
    vol = models.IntegerField(blank=True, null=True, max_length=3)
    year = models.CharField(blank=True, null=True, max_length=20, help_text="Ex) 1980 - present, 1980 - 1989.")
    category = models.CharField(max_length=30, choices=CATEGORY_CHOICES)    
    is_current = models.BooleanField(help_text="Check if the title is being published where Emma makes regular appearances.")
    slug = models.SlugField()
    class Meta:
        ordering = ['title']
    def get_absolute_url(self):
        return "/titles/%s" % self.slug        
    def __unicode__(self):

class Issue(models.Model):
    title = models.ForeignKey(Title)
    number = models.CharField(max_length=20, help_text="Do not include the '#'.")
    ...

Of course, by following the Django docs, the pagination system works when the View is defined by something like this: def view(request):

I'm also wondering how I can pull out the next and previous objects.

I would need a link to the "next issue (with the context of the name and issue number)" and then a "previous issue" link. Please note that simply changing the template link with the next or previous number of the issue is not going to work.

So, if anyone can help me out, that would be great.

like image 727
AAA Avatar asked May 16 '11 11:05

AAA


People also ask

How does Django define class-based views?

Asynchronous class-based viewsimport asyncio from django. http import HttpResponse from django. views import View class AsyncView(View): async def get(self, request, *args, **kwargs): # Perform io-blocking view logic using await, sleep for example. await asyncio.

What is Paginator 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.


2 Answers

Just add paginate_by = 20 to you view class.

class IssuesByTitleView(ListView):
    context_object_name = "issue_list"
    paginate_by = 20

    #More stuff here..
like image 72
Evan Porter Avatar answered Sep 21 '22 16:09

Evan Porter


Just like Evan Porter has commented, you can make use of the page_obj context variable to access number, paginatior.num_pages, has_next, has_previous. This is what just saved me from the KeyError['page'] after upgrading from Django 1.4.1 to 1.7, object_list to ListView

like image 44
AJNinja Avatar answered Sep 21 '22 16:09

AJNinja