How to pass additional arguments to as_view in Django REST framework

In my urls, I want to pass additional arguments like this



But when I do that, I get an error that I can only pass the attributes that are defined in the class.

I tried this

class MyListView(APIView):
    def as_view(self, extra=None, **kwargs):
        self.extra=kwargs.pop('extra', None)
        super(MyListView, self).as_view(**kwargs)


Then I get

unbound method as_view() must be called with MyListView instance as first argument (got nothing instead)



source to share

1 answer

The keyword arguments to invoke MyListView.as_view()

are passed to the method __init__

whenever a view instance is needed (for example, when processing a request); you can override this method to capture the keyword extra


class MyListView(APIView):
    def __init__(self, extra=None, **kwargs):
        self.extra = extra
        super(MyListView, self).__init__(**kwargs)


The method as_view()

must be classmethod; it is not called on a view instance:

class MyListView(APIView):
    def as_view(cls, extra=None, **kwargs):
        cls.extra = extra
        return super(MyListView, cls).as_view(**kwargs)


The keyword argument is extra

explicitly specified, so it will never be found in kwargs

catch-all. You also want to return the result of the call super()


Note that the attribute is extra

also shared among all instances of the view! You can also set it directly in the view class:

class MyListView(APIView):
    extra = 'test'


Since it as_view()

must instantiate, you can add an attribute to the return value of the call super()

before passing it:

class MyListView(APIView):
    def as_view(cls, extra=None, **kwargs):
        view = super(MyListView, cls).as_view(**kwargs)
        view.extra = extra
        return view


but then overriding __init__

means achieving the same result and easier tracking for future maintainers.



All Articles