Django Rest Framework 404 Not Found/PUT/DELETE

When using Django Rest Framework, how do we disable the DELETE button and PUT form from showing on the browsable API when a query returns a 404 Not Found? Thank you.

The PUT and DELETE options may not have a relation with the 404 Not found.

I assume you’re using a ModelViewSet, which provides the HTTP verbs (GET, POST, PUT, PATCH, DELETE).
You can replace the ModelViewSet only with the mixins you need. Look at this example from the docs.
https://www.django-rest-framework.org/api-guide/viewsets/#example_3

Thank you. I actually saw that example already. Is there a way to program the Serializer or View to not show the DELETE button and PUT form when there’s an invalid query that would produce a 404? Thank you again.

Based on my assumption, you should need to exclude the mixins for PUT and DELETE.

class TaskViewset(
     mixins.CreateModelMixin, # POST
     mixins.ListModelMixin, # GET a list of instances
     mixins.RetrieveModelMixin, # GET a single instance
     viewsets.GenericViewSet
)

I recommend you to provide the code of your viewset so we can give better advice.

I don’t want to exclude the PUT and DELETE when there is a valid response from a query, only when the query returns an invalid response such as 404.

class TaskViewSet(viewsets.ModelViewSet):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer
    permission_classes = [
        permissions.IsAuthenticatedOrReadOnly,
        IsOwnerOrReadOnly
    ]

BTW, the same problem occurs in the Snippets example put out by Django Rest Framework as well. So, it’s something that is not addressed in the tutorial. IF anyone knows how to fix this, please share. Thank you in advance!

Couple different thoughts here:

The HTTP PUT request method creates a new resource or replaces a representation of the target resource with the request payload.

This means that having a PUT option for an entry that doesn’t exist would be appropriate for the creation of that entry.

Thank you. I will try the alternative channel. If I find a solution, may I still share it here?

Here’s the solution I found that works, thanks to a bit of searching. In renderers.py file in the app directory, create a custom BrowsableAPIRenderer class and override get_context() and get_rendered_html_form(). The first method sets the context for display on the PUT HTML form. The latter method disables the DELETE button from showing.

# renderers.py
from rest_framework.renderers import BrowsableAPIRenderer

class MyBrowsableAPIRenderer(BrowsableAPIRenderer):

    """
    Only render the browsable API if there is no 404 error
    """

    def get_context(self, *args, **kwargs):
        context = super().get_context(*args, **kwargs)

        response = args[2]['response']
        if response.status_code == 404:
            # do not display PUT form
            context['display_edit_forms'] = False

        return context

    def get_rendered_html_form(self, data, view, method, request):
       """
       {
          "detail": "Not found."
       }
       """
        if 'detail' in data:
            return
        return super().get_rendered_html_form(data, view, method,  request)

In settings.py file, add these settings to use the default JSONRenderer and our custom MyBrowsableAPIRenderer:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'planner.renderers.MyBrowsableAPIRenderer',
    ),
}

Hope this helps!!