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:
-
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
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!!