“ def post”和“ if.request.method == POST”是否相同?

时间:2018-06-19 14:57:41

标签: python django

$hashSorteddef post是否相同?

我看到有些使用if.request.method == POST,有些使用def post(self, request)。它们似乎都可以正常工作,至少对于我所见过的任务而言。

有区别吗?

2 个答案:

答案 0 :(得分:9)

我认为您混合了两种主要的Django方法:function-based viewsclass-based views
if request.method == POST-FBV,
def post(self, request)-CBV。
在FBV中,您通常将视图编写为函数,在其中有条件地检查采用哪种方法。在CBV中,您将重写一些Django内置类和该类中的内置方法。
是的,这是相同的动作。
附言对于初学者来说,开始学习基于函数的视图会更容易。

答案 1 :(得分:2)

我假设您正在谈论基于类的视图。在这种情况下,如果您更改路由机制,则答案为

让我们看看source code of the View class [GitHub]。通常,基于类的视图是此类的子类,从而继承了此类的行为:

class View:

    # ...

    http_method_names = ['get', 'post', 'put', 'patch',
                         'delete', 'head', 'options', 'trace']

    # ...

    @classonlymethod
    def as_view(cls, **initkwargs):
        # ...
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.request = request
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)
        # ...
        return view

    def dispatch(self, request, *args, **kwargs):
        # ...
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), 
                                 self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)


    # ...

我在这里剥离了或多或少无关紧要的部分,并修复了一些格式,以便于阅读。

如您所见,如果调用as_view()函数(当您声明url(..)path(..)时,则它基本上构造了一个函数def view(..),并且该功能的引用与此URL链接。

现在view(..)函数可以执行一些操作(例如,如果未实现head (...)函数,则稍后会退回到get (..)函数。但是,最重要的部分是它调用self.dispatch(..)函数。

此分派功能查找request.method。它将此方法转换为小写变量,然后检查该方法是否在视图中声明。如果是,它将调用相应的方法(因此在request.method == 'POST'的情况下,它将使用post (...)request*args来调用**kwargs),并且如果缺少该方法,则基本上会返回“ HTTP方法不允许响应”。

但是请注意,您可以将as_viewdispatch(..)函数子类化,从而改变这种行为。

更严格地说,您可以编写自己的View类,它当然可以具有完全不同的行为,但是我认为这实际上并不是此问题的范围。

因此,基于类的视图基本上执行类似的操作(这不是代码的样子,但是从语义上来说,它大致相同):

def some_view(request, *args, **kwargs):
    if request.method == 'GET':
        return self.get(request, *args, **kwargs)
    if request.method == 'POST':
        return self.post(request, *args, **kwargs)
    if request.method == 'PUT':
        return self.put(request, *args, **kwargs)
    if request.method == 'PATCH':
        return self.patch(request, *args, **kwargs)
    if request.method == 'DELETE':
        return self.delete(request, *args, **kwargs)
    if request.method == 'HEAD':
        return self.head(request, *args, **kwargs)
    if request.method == 'OPTIONS':
        return self.options(request, *args, **kwargs)
    if request.method == 'TRACE':
        return self.trace(request, *args, **kwargs)
    else:
        return self.http_method_not_allowed(request, *args, **kwargs)

当然,所有这些功能都存在(并非总是 )。此外,options(..)函数是自动生成的:它检查定义了哪些 函数,并返回相应方法的列表。