如何在 Django 1.3 中使用基于类的视图重定向条件?

Posted

技术标签:

【中文标题】如何在 Django 1.3 中使用基于类的视图重定向条件?【英文标题】:How to redirect on conditions with class based views in Django 1.3? 【发布时间】:2011-07-22 22:26:25 【问题描述】:

我正在使用根据标签列出视频的 ListView。过滤发生在 get_queryset() 中。如果标签不包含任何视频,我想将用户重定向到另一个页面。

有了函数,就很容易了。查询,检查查询集,重定向。在上课时,我没有这样做:

class VideosView(generic.ListView):

    def get_queryset(self):
        """
            This work.
        """

        tag = self.kwargs.get('tag', None)

        self.videos = Video.on_site.all()

        if tag:
            self.videos = Video.tagged.with_all(tag, self.videos)

        return self.videos

    def get(self, request, *args, **kwargs):
        """
        This doesn't work because self.videos doesn't exist yet.
        """
        if not self.videos:
            return redirect('other_page')

        return super(Videos, self).get(request, *args, **kwargs)

【问题讨论】:

【参考方案1】:

我知道这已经过时了,但我实际上同意 Tommaso。 dispatch() 方法负责处理请求并返回 HTTP 响应。如果您想调整视图的响应,那就是这样做的地方。这是 dispatch() 上的 docs。

class VideosView(ListView):
    # use model manager
    queryset = Videos.on_site.all()

    def dispatch(self, request, *args, **kwargs):
        # check if there is some video onsite
        if not queryset:
            return redirect('other_page')
        else:
            return super(VideosView, self).dispatch(request, *args, **kwargs)

    # other method overrides here

【讨论】:

如果查询集是动态的,你如何得到它? 您应该仍然有一个可用的查询集对象。你有例子吗? 如果我没记错的话,ListView 在 get_queryset 中生成动态查询集,然后在 get_context 中进行分页。使用 dispatch 似乎会调用它们,如果您想根据它进行重定向,这很不酷。 首先,它会被dispatch()第二次调用,其次,你不会得到分页版本。 但是您需要分页逻辑根据查询集进行重定向。你怎么知道当前分页查询集的内容?在您的情况下,您将只有整个查询集。完全不一样。【参考方案2】:

找到了:

def render_to_response(self, context):

    if not self.videos:
        return redirect('other_page')

    return super(VideosView, self).render_to_response(context)

所有 HTTP 方法都调用此方法

【讨论】:

我同意这个方案,但是你不觉得view的dispatch方式更合适吗? 好吧,dispatch 将调用 get 或 post 方法,这些方法调用查询集来获取视频列表,所以它对我来说并不那么自然。为什么你认为它会更好? 这里是 redirect 上的 django 1.3 文档 答案将受益于更多的上下文。我猜有一个基本的 get_queryset 函数,没有 get/post HTTP 方法处理程序 get_query_set 函数。您通常不想做很多“工作”,然后只是在请求的最后进行重定向。如果可以在访问查询集之前/不访问查询集之前确定需要重定向,那么 Dispatch 方法将是一个更好的地方。【参考方案3】:

根据 django doc :

在 url.py 中

from django.views.generic.base import RedirectView

urlpatterns = patterns('',
     ...
    url(r'^go-to-django/$', RedirectView.as_view(url='http://djangoproject.com'), name='go-to-django'),
..
)

【讨论】:

它完全忘记了OP中的条件部分。

以上是关于如何在 Django 1.3 中使用基于类的视图重定向条件?的主要内容,如果未能解决你的问题,请参考以下文章

Django 基于类的通用视图和身份验证

Django - 基于类的通用视图 - “没有要重定向到的 URL”

如何在 django 中使用基于类的视图

如何使用基于类的视图在同一模板中使用两个不同的 Django 表单

Django 基于类的视图上的 success_url 的反向抱怨循环导入

Django:在基于类的视图中包含媒体(css/js)