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
]
Couple different thoughts here:
-
Django Rest Framework is not part of the Django project - there is a separate support channel available for it. You may get more direct substantial help through it.
-
I don’t believe having a PUT option is an “error”. Quoting from https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT:
The HTTP
PUTrequest 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!!


