Ross Rogers
Ross Rogers

Reputation: 24270

How do you override a ModelViewSet's get_queryset in Django Rest Framework 3?

I used to follow this pattern in Django Rest Framework (DRF) 2:

class Foo(models.Model):
    user = models.ForeignKey(User)

class FooSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Foo
        fields = ('url')

class FooViewset(viewsets.ModelViewSet):
    def get_queryset(self):
        return Foo.objects.filter(user=self.request.user)
    serializer = FooSerializer
    model = Foo # <-- the way a ModelViewSet is told what the object is in DRF 2

[ in urls.py]
from rest_framework import routers
router = routers.DefaultRouter()
router.register('Foo', views.FooViewSet)

In DRF 3, I now get:

AssertionError at /
`base_name` argument not specified, and could not automatically  
 determine the name from the viewset, as it does not have a   
`.queryset` attribute.

How is get_queryset overridden for an instance of rest_framework.viewsets.ModelViewSet?

Upvotes: 16

Views: 19824

Answers (3)

bizi
bizi

Reputation: 3457

In addition to Ross Rogers' answer, on current version (3.8.2), you can specify only the model's name instead of the handler. So, instead of:

router.register('/rest/FooBar', views.FooBarViewSet, base_name='foobar-list')
router.register('/rest/FooBar/{pk}', views.FooBarViewSet, base_name='foobar-detail')

You can just do:

router.register('/rest/FooBar', views.FooBarViewSet, base_name='foobar')

Upvotes: 4

Ross Rogers
Ross Rogers

Reputation: 24270

Figured this one out. The model field of the rest_framework.viewsets.ModelViewSet does seem to be AWOL in DRF3. Now, if you override get_queryset you need to specify a third parameter to routers.DefaultRouter().register which is the basename parameter. Then, the function won't go off and try to find it on the non-existent queryset field of the ModelViewSet.

e.g.

router = routers.DefaultRouter()
[...]
router.register('/rest/FooBar'/, views.FooBarViewSet, 'foobar-detail')
                                                     #^^^^^^^^^^^^^^^

Upvotes: 22

levi
levi

Reputation: 22697

To overrite default queryset in DRF 3, just define queryset attribute whitin your FooViewSet class.

class FooViewset(viewsets.ModelViewSet):
     queryset = Foo.objects.all()

Upvotes: -3

Related Questions