5

I'm getting the following error even though my view is overriding get_queryset().

AssertionError: Cannot apply DjangoModelPermissions on a view that does not set `.queryset` or have a `.get_queryset()` method.

Here's my view:

class PlayerViewSet(viewsets.ModelViewSet):

    serializer_class = PlayerSerializer

    def get_queryset(self):
        try:
            quality = self.kwargs['quality'].lower()
            print("Getting Player for %s"%quality)
            return Player.objects.filter(qualities__contains=quality)
        except:
            # todo: send out a 404
            print("No Players found for this quality :(")
            pass

My settings.py:

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ]
}

Edit - Additional info: Here's the entry in urls.py:

router = routers.DefaultRouter()
router.register(r'^player-list/(?P<quality>\w+)', players.views.PlayerViewSet, base_name="Player List")
[...]
urlpatterns = [
    url(r'^api/', include(router.urls)),
] 

I don't understand what the issue is. Why doesn't DRF see my get_queryset method?

Jad S
  • 2,705
  • 6
  • 29
  • 49

1 Answers1

0

I've tried running your code on DRF 3.3.2 and could figure out a couple of easy to miss errors that may be leading to the AssertionError you mentioned.

  1. Misspelled get_queryset(). Looks fine in your question here, but double check your code to be sure.
  2. In your code in get_queryset, you return None in the case of an exception. I tried forcing an exception in under get_querysetand silencing it the way you've done (returning None at the end). This lead to the exact AssertionError. So make sure your code under get_querysetisn't raising any exceptions. One area where I think an exception could be raised is when the named url group 'quality' isn't passed into self.kwargs.

Sidenote: When DRF calls the permission class' has_permission method, it sends the api view as an argument. It then uses the api view to figure out what your queryset is. If you can set up a debugger at 'rest_framework/permissions.py' (here) and pause inside the has_permission method, you can then double check if the queryset variable is correctly picked up, or is set to None. In your case, it is probably coming up as None which is whats triggering the AssertionError, you can then check if the api_view instance passed on to the function as a parameter, actually refers to an instance of PlayerViewSet or not.

arijeet
  • 1,858
  • 18
  • 26