On Mon, 2006-04-24 at 01:23 +0000, Alexis Smirnov wrote:
> Some of the URLs in my django application are addressable by both POST
> and GET requests. This results in the code like this:
> 
> urls.py:
> 
> from django.conf.urls.defaults import *
> 
> urlpatterns = patterns('',
>     (r'^myapp/myresource/$', 'myproj.myapp.myresource'),
>     ....
> 
> views.py:
> ...
> def myresource(request):
>     if request.META['REQUEST_METHOD'] == 'GET':
>         return get_myresource(request)
>     elif request.META['REQUEST_METHOD'] == 'POST':
>         return post_myresource(request)
> 
> def get_myresource(request):
> ...
> def post_myresource(request):
> ...
> 
> 
> Being new to django, I'm wondering if this kind of approach is what
> people are generally using? 

More or less, in my case. I don't always dispatch immediately (or at
all).

> It would seem it could lead to a non-DRY
> repetitive code.

On the contrary: because all request methods pass through the same code
path initially, it is easy to factor out commonality. For example, if
the representation returned from a POST request (after creating the
object) is the same as would be returned by a GET to the same -- or a
similar -- URL, then you can just flow through the same code path.

Repeating yourself may happen if you immediately and unfailingly
dispatch to separate handler functions as in your example. But in cases
where you have common pieces, it is usually easy enough to organise them
in the main body or in a common function to do the work.

> What is the best way to dispatch to a method based on both HTTP method
> *and* a URL? If such method isn't available within the framework, was
> it already considered adding an HTTP method to the url patterns data
> structure?

If you always want to dispatch to separate methods, what you have given
above is easy and straightforward. Your email seems to suggest you
believe otherwise (it is already available in the framework, as you
demonstrate -- you have access to the method easily), but I think the
current setup is a pretty good choice balancing ease-of-use with maximum
flexibility for implementors.

You could write your example slightly more compactly as something like

        func = {'GET': get_myresourse,
            'POST': post_myresource}[reqest.META['REQUEST_METHOD']
        return func(request)

if you are worried about the length of boilerplate code. This extends
smoothly to any number of request methods and is sometimes given as an
idiomatic way to write switch statements in Python (although clarity is
sacrificed for conciseness in some cases)

A drawback of putting the method in the URLConf structure would be
handling invalid methods on a resource.

Of course, all this is just based on the way I work and the types of
applications I write, so opinions may vary. But I have used a lot of
frameworks over the years and Dango's handling of this case seems pretty
nice and natural to me.

Cheers,
Malcolm


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~----------~----~----~----~------~----~------~--~---

Reply via email to