首页 > 解决方案 > 如何覆盖 Django 通用基础视图的调度方法?

问题描述

如果我编写一个继承自 Django 通用基础视图的类,那么覆盖其调度方法的正确方法是什么?该文档似乎表明它可以被覆盖,但该示例并未准确显示如何执行此操作。

如果我这样做,

class MyView(View):
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        response = dispatch(request, *args, **kwargs)
        return HttpResponse('Hello, world!')

姜戈说,

NameError: name 'dispatch' is not defined.

如果我然后将调度语句更改为此,

response = self.dispatch(request, *args, **kwargs)

姜戈说,

RecursionError: maximum recursion depth exceeded

标签: django

解决方案


该文档似乎表明它可以被覆盖,但该示例并未准确显示如何执行此操作。

您可以覆盖每个方法(除了一些 Python 内置函数等,但这里不相关)。

然而,覆盖dispatch并不常见,因为dispatch基本上检查请求的方法(GET、POST、PATCH、PUT、DELETE 等)到相应的方法getpostpatchputdelete等。

所以,正如你所发现的,如果你在方法中调用方法,你会得到一个相互递归的情况。这里会叫,也会叫。所以这将继续相互调用,直到调用堆栈耗尽。dispatch()get()dispatchgetgetdispatch

在某些情况下,视图会覆盖该dispatch方法,例如这样LogoutView做 [GitHub]

class LogoutView(SuccessURLAllowedHostsMixin, TemplateView):

    # …

    @method_decorator(never_cache)
    def dispatch(self, request, *args, **kwargs):
        auth_logout(request)
        next_page = self.get_next_page()
        if next_page:
            # Redirect to this page until the session has been cleared.
            return HttpResponseRedirect(next_page)
        return super().dispatch(request, *args, **kwargs)

在这里,该dispatch方法将确保logout为给定用户进行调用。但是该get方法不会dispatch再次调用该方法。


推荐阅读