How to pass additional arguments to as_view in Django REST framework
In my urls, I want to pass additional arguments like this
MyListView.as_view(extra="test")
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
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):
@classmethod
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):
@classmethod
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.
source to share