Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass additional args in as_view in Django REST framework

In my urls I want to pass additional args like this

MyListView.as_view(extra="test")

But when I do that then I get error that I can only pass those attributes which are defined in 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)
like image 379
user3214546 Avatar asked Sep 05 '25 03:09

user3214546


1 Answers

The keyword arguments to the MyListView.as_view() call are passed to the __init__ method each time a view instance is needed (e.g. when handling a request); you can override that method to capture the extra keyword:

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

The as_view() method must be a classmethod; it is not called on an instance of the view:

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

The extra keyword argument is explicitly named so it'll never be found in the kwargs catch-all. You also want to return the result of the super() call.

Note that the extra attribute is then also shared between all instances of the view! You may as well set it directly on the view class:

class MyListView(APIView):
    extra = 'test'

Since as_view() must produce an instance, you can add the attribute on the return value of the super() call before passing it on:

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 the __init__ is achieving the same result and easier to follow for future maintainers.

like image 121
Martijn Pieters Avatar answered Sep 07 '25 19:09

Martijn Pieters