DEV Community

Discussion on: Managing RESTful URLs in Django Rest Framework

Collapse
 
darland profile image
Artem Tiumentcev

Thanks, your solution was very helpful to me.

In your example, I received 500 errors if a method does not allow

AssertionError: .accepted_renderer not set on Response
Enter fullscreen mode Exit fullscreen mode

I replaced the Response method on the parent method call, where I got normal behaviour and error 405.

def dispatch(self, request, *args, **kwargs):
    if not hasattr(self, 'VIEWS_BY_METHOD'):
        raise Exception('VIEWS_BY_METHOD static dictionary variable must be defined on a ManageView class!')
    if request.method in self.VIEWS_BY_METHOD:
        return self.VIEWS_BY_METHOD[request.method]()(request, *args, **kwargs)

    return super().dispatch(request, *args, **kwargs)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
loicgasser profile image
Gasser Loïc

This now results in this error

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

This is what I ended up using:

    def dispatch(self, request, *args, **kwargs):
        if not hasattr(self, 'VIEWS_BY_METHOD'):
            raise Exception(
                'VIEWS_BY_METHOD static dictinary must be defined')
        if request.method in self.VIEWS_BY_METHOD:  # pylint: disable=E1101
            return self.VIEWS_BY_METHOD[  # pylint: disable=E1101
                request.method
            ]()(request, *args, **kwargs)

        response = Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
        if not getattr(request, 'accepted_renderer', None):
            neg = self.perform_content_negotiation(request, force=True)
            request.accepted_renderer, request.accepted_media_type = neg

        response.accepted_renderer = request.accepted_renderer
        response.accepted_media_type = request.accepted_media_type
        response.renderer_context = self.get_renderer_context()
        return response
Enter fullscreen mode Exit fullscreen mode
Collapse
 
biskark profile image
Kevin

I had the same issue and found that using a predefined Response type instead of the general Response class fixed it.

E.g.

    from django.http import JsonResponse

    def dispatch(self, request, *args, **kwargs):
        if not hasattr(self, 'VIEWS_BY_METHOD'):
            raise Exception(
                'VIEWS_BY_METHOD static dictinary must be defined')
        if request.method in self.VIEWS_BY_METHOD:  # pylint: disable=E1101
            return self.VIEWS_BY_METHOD[  # pylint: disable=E1101
                request.method
            ]()(request, *args, **kwargs)

        return JsonResponse(data={}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
Enter fullscreen mode Exit fullscreen mode

I haven't tested others, but I assume this would work equally well with an HttpResponse or whichever.