0

I found a partial solution in Django: How to catch InvalidPage exception in class-based views?, but the URL in the address bar still shows the original page request. Django has Paginator.get_page(number), but there doesn't seem to be a way to use it to redirect inside of the view.

I originally thought I might be able to do it in get_context_data, but I don't seem to be able to force a redirect as it will only allow a dict as a response.

def get_context_data(self, **kwargs):
        paginator = self.get_paginator(self.queryset,self.paginate_by,self.paginate_orphans)
        try:
            context = super().get_context_data(**kwargs)
        except Http404 as err:
            self.kwargs['page'] = paginator.get_page(self.request.GET['page']).number
            return redirect('my_list_view', kwargs=self.kwargs)

        context['page_list'] = context['paginator'].get_elided_page_range(context['page_obj'].number,on_each_side=2,on_ends=1)

        return context

That fails outright. The following works (per the linked answer above), but does so in a non-optimal way.

def get_context_data(self, **kwargs):
        paginator = self.get_paginator(self.queryset,self.paginate_by,self.paginate_orphans)
        try:
            context = super().get_context_data(**kwargs)
        except Http404 as err:
            self.kwargs['page'] = paginator.get_page(self.request.GET['page']).number
            context = super().get_context_data(**kwargs)

        context['page_list'] = context['paginator'].get_elided_page_range(context['page_obj'].number,on_each_side=2,on_ends=1)

        return context

I feel like there should be a simple/elegant way to do this, but I just haven't found one. I could of course go for a function-based view, but I can't shake the feeling that there's got to be a way to do it this way.

1 Answers1

0

Update

After much more work... I still haven't found anything I like. Turns out the method below breaks some of the dynamic filtering capabilities of Django because of when/how the querysets are filtered. I may just allow for 404s when an invalid page is entered.

Also, I've discovered furl for manipulating urls. Much easier to edit or remove or add parameters this way, while also making sure that everything is safe and valid.

Would still love someone to point me to something more elegant.


Original

Well, after some more work, this works, but seems inelegant, at best. I'm not marking this as the correct answer (yet) because I don't really like it and I'm hoping for someone to provide something better, but thought I'd throw it out there. Used answers from Redirect from Generic View DetailView in Django to guide me.

def get(self, request, *args, **kwargs):
        paginator = self.get_paginator(self.queryset,self.paginate_by,self.paginate_orphans)
        try:
            page = self.request.GET['page']
        except:
            return super().get(request, *args, **kwargs)
        
        page_new = paginator.get_page(page)
        try:
            page_int = int(page)
            if page_int != page_new.number:
                redirect_url = reverse_lazy('home') + "?page=" + str(page_new.number)
            else:
                return super().get(request, *args, **kwargs)
        except:
            redirect_url = reverse_lazy('home') + "?page=" + str(page_new.number)
        
        return redirect(redirect_url)