user3214546
user3214546

Reputation: 6831

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)

Upvotes: 4

Views: 3889

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122342

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.

Upvotes: 6

Related Questions