Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to discriminate based on HTTP method in django urlpatterns

I'm having some difficulties finding information about this, probably it's not the right approach. I'd like to route a request to two different view functions based on the http method (GET or POST or DELETE or PUT).

As it is usually done in REST apis, this would mean that the same url has different meaning based on the HTTP method.

I don't see a way to do this in the urls.py file of django, I'd like something like:

url(r'^tasks$', 'app.views.get_tasks', method='get'), url(r'^tasks$', 'app.views.create_task',  method='post'), 

(note: I'm working with django 1.4)

like image 550
luca Avatar asked Sep 30 '13 14:09

luca


People also ask

What happens when a URL is matched Django?

Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL, matching against path_info . Once one of the URL patterns matches, Django imports and calls the given view, which is a Python function (or a class-based view).

What is the difference between URL and path in Django?

The path function is contained with the django. urls module within the Django project code base. path is used for routing URLs to the appropriate view functions within a Django application using the URL dispatcher.


2 Answers

I don't think you can do this with different functions without adding a bunch of logic to the URL (which is never a good idea), but you can check inside the function for the request method:

def myview(request):     if request.method == 'GET':         # Code for GET requests     elif request.method == 'POST':         # Code for POST requests 

You could also switch to class-based views. You would then only need to define a method for each of the HTTP methods:

class CreateMyModelView(CreateView):     def get(self, request, *args, **kwargs):         # Code for GET requests      def post(self, request, *args, **kwargs):         # Code for POST requests 

If you decide to go the class-based route, another good resource is http://ccbv.co.uk/.

like image 159
hellsgate Avatar answered Sep 24 '22 14:09

hellsgate


Because Django allows you to use callables in url config, you can do it with a helper function.

def method_dispatch(**table):     def invalid_method(request, *args, **kwargs):         logger.warning('Method Not Allowed (%s): %s', request.method, request.path,             extra={                 'status_code': 405,                 'request': request             }         )         return HttpResponseNotAllowed(table.keys())      def d(request, *args, **kwargs):         handler = table.get(request.method, invalid_method)         return handler(request, *args, **kwargs)     return d 

To use it:

url(r'^foo',     method_dispatch(POST = post_handler,                     GET = get_handler)), 
like image 23
Juri Pakaste Avatar answered Sep 25 '22 14:09

Juri Pakaste