Search code examples
djangoapirestdjango-rest-frameworkcrud

How to allow only custom urls in Django rest api?


I'm trying to create a simple api to learn how Django works. I'm using rest_framework.

First, I have created a model:

class User(models.Model):
    username = models.CharField(max_length=20, primary_key=True)
    password = models.CharField(max_length=50)
    token = models.UUIDField(default=uuid.uuid4, editable=False)
    creation_dt = models.DateTimeField(auto_now_add=True)

Then I have created a serializer:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'password', 'token', 'creation_dt')
        read_only_fields = ('creation_dt', 'token',)

And then, in api.py, this code:

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    permission_classes = [permissions.AllowAny]
    serializer_class = UserSerializer
    http_method_names = ['get', 'post']

    @action(methods=['POST'], detail=False, permission_classes=[permissions.AllowAny], url_path='get_all_users')
    def get_all_users(self, request, pk=None):
        ...
        return Response(UserSerializer(self.queryset[:user_number], 

As you can see, I added a custom url_path "get_all_users".

So, everything works until here. My problem is that I can still access "/users/", "/users/user_name", POST users etc, the normal CRUD app.

The question is, how can I allow only the url I have especifially created and block all the rest created automatically?

Thanks.


Solution

  • Apparently just changing ModelViewSet to GenericViewSet works.

    class UserViewSet(viewsets.GenericViewSet):
        queryset = User.objects.all()
        permission_classes = [permissions.AllowAny]
        serializer_class = UserSerializer
        http_method_names = ['get', 'post']
    
        @action(methods=['POST'], detail=False, permission_classes=[permissions.AllowAny], url_path='get_all_users')
        def get_all_users(self, request, pk=None):
            ...
            return Response(UserSerializer(self.queryset[:user_number], 
    

    Only our custom URLs will be exposed and not the default ones (CRUD).