如何在 Django REST 框架中的 as_view 中传递额外的参数

use*_*546 3 python django django-rest-framework

在我的网址中,我想传递这样的额外参数

MyListView.as_view(extra="test")
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时,我得到错误,我只能传递那些在类中定义的属性。

我试过这个

class MyListView(APIView):
    def as_view(self, extra=None, **kwargs):
        self.extra=kwargs.pop('extra', None)
        super(MyListView, self).as_view(**kwargs)
Run Code Online (Sandbox Code Playgroud)

然后我得到

unbound method as_view() must be called with MyListView instance as first argument (got nothing instead)
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 6

每次需要视图实例时(例如处理请求时),MyListView.as_view()调用的关键字参数都会传递给__init__方法;您可以覆盖该方法以捕获extra关键字:

class MyListView(APIView):
    def __init__(self, extra=None, **kwargs):
        self.extra = extra
        super(MyListView, self).__init__(**kwargs)
Run Code Online (Sandbox Code Playgroud)

as_view()方法必须是一个类方法;它不会在视图的实例上调用:

class MyListView(APIView):
    @classmethod
    def as_view(cls, extra=None, **kwargs):
        cls.extra = extra
        return super(MyListView, cls).as_view(**kwargs)
Run Code Online (Sandbox Code Playgroud)

extra关键字参数被明确命名,以便它永远不会在找到kwargs包罗万象的。您还想返回super()调用的结果。

请注意,该extra属性也会在视图的所有实例之间共享!你也可以直接在视图类上设置:

class MyListView(APIView):
    extra = 'test'
Run Code Online (Sandbox Code Playgroud)

由于as_view()必须生成一个实例,您可以super()在传递它之前在调用的返回值上添加属性:

class MyListView(APIView):
    @classmethod
    def as_view(cls, extra=None, **kwargs):
        view = super(MyListView, cls).as_view(**kwargs)
        view.extra = extra
        return view
Run Code Online (Sandbox Code Playgroud)

但随后覆盖__init__是实现相同的结果并且更容易为未来的维护者遵循。