0

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

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

我的视图使用 CreateView 并且我自己实现了 form_invalid 以便将一些数据添加到上下文变量中。在我的 form_invalid 方法结束时,我返回self.render_to_response(context)

问题

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

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

谢谢

4

2 回答 2

1

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

谢谢@petkostas 指出HTTP_REFERER

我对此的解决方案涉及使用从当前时间戳派生的缓存键将上下文存储在缓存中。我重定向到(相同的)评论 url,但在这样做时,我将当前评论页面作为获取参数附加,并将时间戳作为另一个获取参数。

然后在获取请求期间,视图检查时间戳参数是否存在。如果提供,则调用 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
于 2014-01-28T22:42:37.897 回答
0

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

request.META.get('HTTP_REFERER')

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

request.full_path()
于 2014-01-21T21:32:17.070 回答