[Answer]-Django: How to return user to correct pagination page after CreateView form_invalid?

1👍

This problem is similar to this SO question, but my scenario is a little different given that I want to maintain my form state (the captcha error mentioned in question) in the redirect.

Thank you @petkostas for pointing out HTTP_REFERER

My resolution to this involved storing the context in cache with a cache key derived from the current timestamp. I redirect to the (same) comments url, but in doing this I append the current comment page as a get parameter and also the timestamp as another get parameter.

Then during get requests the view checks for the existence of the timestamp parameter. If it is provided, then a cache.get call is made to retrieve the needed context data. And finally, the cached item is deleted.

from datetime import datetime
from django.core.cache import cache
from django.shortcuts import redirect
from django.utils.dateformat import format

class MyView(CreateView):
    def form_invalid(self, form, **kwargs):
        context = {
            'form': form,
            ... other context stuff ...
        }

        timestamp = format(datetime.now(), u'U')
        cache.set('invalid_context_{0}'.format(timestamp), context)

        page = 1
        full_path = self.request.META.get('HTTP_REFERER')
        if '?' in full_path:
            query_string = full_path.split('?')[1].split('&')
            for q in query_string:
                if q.startswith('page='):
                    page = q.split('=')[1]

        response = redirect('my_comments_page')
        response['Location'] += '?page={0}&x={1}'.format(page, timestamp)
        return response

    def get_context_data(self, **kwargs):
        context = super(MyView, self).get_context_data(**kwargs)
        context.update({
           ... add context stuff ...
        })

        if 'x' in self.request.GET:
            x = self.request.GET.get('x')
            cache_key = 'invalid_context_{0}'.format(x)
            invalid_context = cache.get(cache_key)
            if invalid_context:
                context.update(invalid_context)
                cache.delete(cache_key)
        return context

0👍

I haven’t used django-endless-pagination, but Django offers 2 ways to get either the full current request path, or the Refferer of the request:
In your view or template (check documentation on how to use request in templates) for the referring requesting page:

request.META.get('HTTP_REFERER')

Or for the current request full path:

request.full_path()

Leave a comment