Sandro Meireles
Sandro Meireles

Reputation: 45

Use the same route for with 2 different viewsets, one for writing and one for reading

I have 2 viewsets one for read and other to write:

class MenuReadViewSet(viewsets.ReadOnlyModelViewSet):
    
    serializer_class = MenuSerializer
    queryset = Menu.objects
    filter_class = RelatedEstablishmentFilter
    
    
class MenuWriteViewSet(mixins.CreateModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       viewsets.GenericViewSet):
    
    serializer_class = MenuSerializer

In my urls.py

...

router = routers.DefaultRouter()
router.register("menus", views.MenuReadViewSet, basename="menu-read")
router.register("menus", views.MenuWriteViewSet, basename="menu-write")

urlpatterns = [
    path("", include(router.urls))
]

The problem is, when i send a POST, PUT or DELETE , returns this response:

{
  "detail": "Method <METHOD> not allowed"
}

It seems that the route considers only the first viewset. Exists a simple way to solve this?

Upvotes: 0

Views: 583

Answers (1)

Tom Wojcik
Tom Wojcik

Reputation: 6179

Per your comment

different permissions classes for read and write

Just use different permission classes but within a single ModelViewSet.

class MenuViewSet(viewsets.ModelViewSet):
    serializer_class = MenuSerializer
    queryset = Menu.objects
    filter_class = RelatedEstablishmentFilter
    permission_classes = [MenuPermissionClass]
    
    def get_permissions(self):
        if self.action in ['retrieve', 'list']:
            perms = [ReadOnlyMenuPermission]
        else:
            perms = self.permission_classes
        return [p() for p in perms]

Or handle it in your permission.

from rest_framework.permissions import SAFE_METHODS

...

    def has_object_permission(self, request, view, obj) -> bool:
        if request.method in SAFE_METHODS:
            # todo: ro permission
        ...

Upvotes: 2

Related Questions