Django:如何在CreateView form_invalid之后将用户返回到正确的分页页面?

时间:2014-01-21 21:22:12

标签: django django-views django-pagination

我有一个分页评论页面。分页由django-endless-pagination提供。单击新的分页页面时,会将一个get参数附加到URL。例如?page=4

每个分页页面上的每条评论都会显示一个包含验证码字段的“回复”评论表单。

我的视图使用CreateView,我自己实现form_invalid,以便向上下文变量添加一些数据。在form_invalid方法的最后,我返回self.render_to_response(context)

问题

如果用户在第4页上尝试回复评论,并且该用户提供了无效的验证码,则在回复期间,分页获取参数(?page=4)将丢失。

如何重定向到完整路径(保持获取参数)并传递上下文数据?

由于

2 个答案:

答案 0 :(得分:1)

这个问题类似于this SO question,但我的情况有点不同,因为我想在重定向中维护我的表单状态(提到的验证码错误)。

感谢@petkostas指出HTTP_REFERER

我对此的解决方法包括使用从当前时间戳派生的缓存密钥将上下文存储在缓存中。我重定向到(相同的)注释url,但在执行此操作时,我将当前注释页面添加为get参数,并将时间戳添加为另一个get参数。

然后在get请求期间,视图检查是否存在timestamp参数。如果提供了,则进行cache.get调用以检索所需的上下文数据。最后,缓存的项目将被删除。

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

答案 1 :(得分:0)

我没有使用django-endless-pagination,但是Django提供了两种获取完整当前请求路径或请求的Refferer的方法: 在您的视图或模板中(查看有关如何在模板中使用请求的文档),以获取引用请求页面:

request.META.get('HTTP_REFERER')

或者当前请求的完整路径:

request.full_path()