Thomas Junk
Thomas Junk

Reputation: 5676

How to handle request methods in function based views in Django

As I am learning Django I have some questions about the handling of request methods for function based views (FBVs) in Django.

What I found for FBVs:

The URLconf doesn’t look at the request method. In other words, all request methods – POST, GET, HEAD, etc. – will be routed to the same function for the same URL.

from URL-Dispatcher.

require_http_methods(request_method_list)¶ Decorator to require that a view only accepts particular request methods

from View Decorators

Does that mean, I can restrict an URL defined in urls.py to a function which in turn only accepts say PUT-Requests and in case I want to handle DELETE said URL is wasted, since I restricted it to PUT?

Or otherwise, I have to "dispatch" myself within the FBV?

E.g. with request.method == 'PUT'


Alternatively for CBVs

Organization of code related to specific HTTP methods (GET, POST, etc.) can be addressed by separate methods instead of conditional branching.

from Introduction to class-based views


Does that mean, if I want to handle PUT or DELETE in separate functions I have to

a) use a class based view with the verbs being implemented like put() and delete()

b) use DjangoResteFramework only for having APIViews and @api_view(['Put']) as a decorator for FBVs?

Upvotes: 0

Views: 1162

Answers (2)

Shahid Ali
Shahid Ali

Reputation: 87

In you views.

from django.views.decorators.http import require_http_methods

@require_http_methods(["GET", "POST"])
def my_view(request):
    # I can assume now that only GET or POST requests make it this far
    # ...
    pass

https://docs.djangoproject.com/en/5.0/topics/http/decorators/#allowed-http-methods

Upvotes: 0

Maxim Danilov
Maxim Danilov

Reputation: 3360

You can use normal FBV. I think this is not good in Django, but you can:

def myFunctionView(request, *args, **kwargs):
    match request.method:
        case "GET":
            # do some stuff
            return response_for_get
        case "DELETE":
            # do some stuff
            return response_for_delete
        case "PATCH":
            # do some stuff
            return response_for_path
        case _: # post, put, option e.t.c
            # do some stuff
            return response_for_post

It is completely against Django Philosophy, but it is possible. You can made an decorator to send "method not allowed" status for some request.methods. you can use this decorator in urls.py. But i don't understand, why you want to avoid the GCBV, best part of Django views.

Upvotes: 1

Related Questions