Re: Request method in urls.py

2013-04-15 Thread Brantley Harris
On Mon, Apr 15, 2013 at 6:32 PM, Russell Keith-Magee <
russ...@keith-magee.com> wrote:

>
> On Tue, Apr 16, 2013 at 6:12 AM, Brantley Harris wrote:
>
>> Alex, I see http methods as being very basic, a part of the URL itself.
>>  In other words, from the level of the web framework it's pointless to talk
>> about the URL as anything but a pair of request method and path.
>
>
> I couldn't disagree more on this. URLs and HTTP Methods are completely
> different things. They're even covered by different RFCs. No part of the
> URL spec includes mention of the the HTTP method. The HTTP method is part
> of a protocol for modifying resources identified by a URL.
>

> A URL describes a resource. It describes a "thing" that can have "stuff"
> done to it. That's why HTTP methods like GET/PUT/POST/DELETE are sometimes
> called "verbs" - they're "doing" words, describing what you're going to
> "do" to a resource. GET me the resource. PUT a new resource. DELETE the
> current resource.
>
>
The dispatch process is - and should be - a two phase process:
>
>  1) Decide which resource is affected
>  2) Determine how to handle the request that you've received.
>
> So you want to have different behaviour for different verbs? Fine - then
> you put that at level 2. Yes, there's going to be a repeated pattern here,
> so you'd be well served to have some sort of framework to support this --
> which is what the CBV base class is. If you don't like CBVs, feel free to
> propose something else - but don't try and confuse the task of identifying
> a resource with the task of correctly handling a request for a resource.
>

Yes we can write a dispatcher that doesn't care about the verbs.  Wait,
that's what we've already got.

Surely I wasn't being literal when I said that the http methods were a part
of the url, I meant from the standpoint of dispatching a request.

I don't like CBV's. I have proposed something else.  It's a simple keyword
argument to url() that solves half of what CBV's are trying to solve
without completely changing the layout of a project to favor needlessly
complicated mini-frameworks of inheritance as opposed to simple composition
with functions.


>
> To bring it back to your original example:
>
> > url('^objects/$', 'views.create_object', methods=['post', 'put'],
> name='create_object'),
> > url('^objects/$', 'views.get_objects', name='list_objects'),
>
> I completely fail to see the point of having different reverse endpoints
> for these two. At the end of the day, both of them reverse to the same URL
> - '/objects/'. Your proposed usage is presumably something like:
>

> requests.get(reverse('list_objects'))
> requests.post(reverse('create_object'), data)
>
> However, to drive home the point that the verb *isn't* part of the URL,
> the following would also work:
>
> requests.get(reverse('create_objects'))
> requests.post(reverse('list_objects'), data)
>
> That is, you can POST to your "GET" url, and GET from your "POST" URL, and
> you'd *get no error whatsoever*. So… what exactly is the point of having
> different URL names?
>

Views are not resources.  The urls.py file maps from the URL/HTTP/REST
world into the world of python functions.  When you name your views, you're
doing that, naming your views.  You are not naming URL resources.  In fact,
the whole point of reverse() is so that you can change your URLs without
having to touch the rest of your code because you have been referring to
the view.

A simple example would be going from this:
> url('^objects/$', 'views.create_object', methods=['post', 'put'],
name='create_object'),
> url('^objects/$', 'views.get_objects', name='list_objects'),

To this, because you need to match an existing url pattern:
> url('^objects/create/$', 'views.create_object', methods=['post', 'put'],
name='create_object'),
> url('^objects/all/$', 'views.get_objects', name='list_objects'),

Now, you can see I don't have to change the rest of my code, I can merely
continue on.  This isn't just random simplicity, it uncovers the inherit
nature of these abstractions.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-15 Thread Russell Keith-Magee
On Tue, Apr 16, 2013 at 6:12 AM, Brantley Harris wrote:

> Alex, I see http methods as being very basic, a part of the URL itself.
>  In other words, from the level of the web framework it's pointless to talk
> about the URL as anything but a pair of request method and path.


I couldn't disagree more on this. URLs and HTTP Methods are completely
different things. They're even covered by different RFCs. No part of the
URL spec includes mention of the the HTTP method. The HTTP method is part
of a protocol for modifying resources identified by a URL.

A URL describes a resource. It describes a "thing" that can have "stuff"
done to it. That's why HTTP methods like GET/PUT/POST/DELETE are sometimes
called "verbs" - they're "doing" words, describing what you're going to
"do" to a resource. GET me the resource. PUT a new resource. DELETE the
current resource.

The dispatch process is - and should be - a two phase process:

 1) Decide which resource is affected
 2) Determine how to handle the request that you've received.

So you want to have different behaviour for different verbs? Fine - then
you put that at level 2. Yes, there's going to be a repeated pattern here,
so you'd be well served to have some sort of framework to support this --
which is what the CBV base class is. If you don't like CBVs, feel free to
propose something else - but don't try and confuse the task of identifying
a resource with the task of correctly handling a request for a resource.

To bring it back to your original example:

> url('^objects/$', 'views.create_object', methods=['post', 'put'],
name='create_object'),
> url('^objects/$', 'views.get_objects', name='list_objects'),

I completely fail to see the point of having different reverse endpoints
for these two. At the end of the day, both of them reverse to the same URL
- '/objects/'. Your proposed usage is presumably something like:

requests.get(reverse('list_objects'))
requests.post(reverse('create_object'), data)

However, to drive home the point that the verb *isn't* part of the URL, the
following would also work:

requests.get(reverse('create_objects'))
requests.post(reverse('list_objects'), data)

That is, you can POST to your "GET" url, and GET from your "POST" URL, and
you'd *get no error whatsoever*. So… what exactly is the point of having
different URL names?

Unless someone can explain why this is a good idea, count me as a big -1 on
this.

Yours,
Russ Magee %-)

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-15 Thread Brantley Harris
Alex, I see http methods as being very basic, a part of the URL itself.  In 
other words, from the level of the web framework it's pointless to talk 
about the URL as anything but a pair of request method and path. 
 Strangely, I'm not sure I agree with you that intelligent dispatch 
decisions should happen early on.  Rather, I think simple decisions should 
be made early on.

On Monday, April 15, 2013 12:33:42 PM UTC-5, Alex Ogier wrote:
>
> On Mon, Apr 15, 2013 at 1:22 PM, Donald Stufft  > wrote:
>
>>
>> On Apr 15, 2013, at 1:16 PM, Alex Ogier  
>> wrote:
>>
>> The problem I have with fallthrough-based dispatch is that it encourages 
>> really expensive performance-killing patterns, where you end up doing a 
>> linear scan over view functions round-tripping to the database for each one 
>> to see if the view can handle the request. multiurl is sort of nice because 
>> it least it's obvious that what it's doing might be expensive, and the 
>> whole linear scan is collected in one place so if it gets too long it looks 
>> "wrong" in a Joel Spolsky sense.
>>
>>
>> I don't see how including the method in the resolution scheme equates to 
>> hitting the database.
>>
>
> Oh sorry, I wasn't totally clear. I am advocating a system where people 
> are encouraged to make intelligent dispatch decisions like this one early 
> in the routing framework *instead* of with a try-catch-fallthrough pattern. 
> Anything that lets you avoid doing extra work through a little up-front 
> intelligence is a plus in my book, and I think it's a shame that there 
> aren't really any good hooks to make these kinds of intelligent decisions 
> in the routing framework. django-multiurl has already done a lot of the 
> heavy lifting to make multiple URLs for the same regex work in a clean way 
> outside of core, but it uses this onerous pattern of calling views and 
> expecting them to fail in a specific way. So I am proposing that it could 
> easily be made to have all the right hooks to make arbitrary intelligent 
> routing decisions.
>
> I think we're on the same side here, except that you want this in core.
>
> Best,
> Alex Ogier
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-15 Thread Alex Ogier
On Mon, Apr 15, 2013 at 1:22 PM, Donald Stufft  wrote:

>
> On Apr 15, 2013, at 1:16 PM, Alex Ogier  wrote:
>
> The problem I have with fallthrough-based dispatch is that it encourages
> really expensive performance-killing patterns, where you end up doing a
> linear scan over view functions round-tripping to the database for each one
> to see if the view can handle the request. multiurl is sort of nice because
> it least it's obvious that what it's doing might be expensive, and the
> whole linear scan is collected in one place so if it gets too long it looks
> "wrong" in a Joel Spolsky sense.
>
>
> I don't see how including the method in the resolution scheme equates to
> hitting the database.
>

Oh sorry, I wasn't totally clear. I am advocating a system where people are
encouraged to make intelligent dispatch decisions like this one early in
the routing framework *instead* of with a try-catch-fallthrough pattern.
Anything that lets you avoid doing extra work through a little up-front
intelligence is a plus in my book, and I think it's a shame that there
aren't really any good hooks to make these kinds of intelligent decisions
in the routing framework. django-multiurl has already done a lot of the
heavy lifting to make multiple URLs for the same regex work in a clean way
outside of core, but it uses this onerous pattern of calling views and
expecting them to fail in a specific way. So I am proposing that it could
easily be made to have all the right hooks to make arbitrary intelligent
routing decisions.

I think we're on the same side here, except that you want this in core.

Best,
Alex Ogier

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-15 Thread Donald Stufft

On Apr 15, 2013, at 1:16 PM, Alex Ogier  wrote:

> The problem I have with fallthrough-based dispatch is that it encourages 
> really expensive performance-killing patterns, where you end up doing a 
> linear scan over view functions round-tripping to the database for each one 
> to see if the view can handle the request. multiurl is sort of nice because 
> it least it's obvious that what it's doing might be expensive, and the whole 
> linear scan is collected in one place so if it gets too long it looks "wrong" 
> in a Joel Spolsky sense.

I don't see how including the method in the resolution scheme equates to 
hitting the database.

> 
> I think what's really needed is a mechanism for more intelligent dispatch 
> decisions. The machinery is there in principle, and django-multiurl takes 
> advantage of it, but there's a bottleneck which is that in order for a view 
> to be correctly registered as a URL resolver with reversal, you have to go 
> through the narrow waist of the url() factory function. This means that while 
> multiurl is able to pretend to be like include() and delegate to its child 
> URL resolvers (which I think is what makes reverse() work), it can't really 
> add intelligence to its view dispatch, it can only sit on the outside 
> watching responses/catching specific errors, and you end up with N copies of 
> the regex (though perhaps this is actually a good thing, since it means you 
> can pass different arguments to different views).
> 
> So for example, if you wanted to implement your own intelligent dispatch 
> function, you are forced to go digging into the internals to find things like 
> the fact that kwargs passed to the url() function end up as the 
> default_kwargs attribute on RegexURLResolver instances. Maybe the best option 
> is to ask Jacob to extend multiurl to support arbitrary dispatch mechanisms 
> that work in *front* of the URL resolver instead of behind it, maybe via a 
> callback in multiurl. The following looks like it would be just as easily 
> added to multiurl as to core, and not that much more onerous:
> 
> from multiurl import multiurl, method_dispatch
> 
> urlpatterns = patterns('',
> multiurl(
> url('^objects/$', 'views.create_object', methods=['post', 'put'], 
> name='create_object'),
> url('^objects/$', 'views.get_objects', name='list_objects'),
> dispatch = method_dispatch
> )
> )
> 
> You might even convince Jacob to make multiurl do a lot of intelligent things 
> with those kwargs for free (no callback required). For example just have it 
> filter the views it tries to only the set that matches the HTTP method if 
> given. There's probably other types of dispatch that are naturally expressed 
> as properties of the URL object once you allow multiple URL objects per 
> regex, such as dispatching by the Accept or Accept-Language headers. All of 
> this stuff falls under multiurl's purview, at least if and until core 
> supports fallthrough URLs.
> 
> Best,
> Alex Ogier
> 
> 
> On Mon, Apr 15, 2013 at 7:54 AM, Tom Christie  wrote:
> This proposal is actually *very* similar to the 'URL dispatcher fall-though' 
> thread that came up recently.
> 
> I don't think it'd take much adjustment to take Jacob's django-multiurl 
> project and adapt it to deal with method-based dispatching rather than 
> fall-through based dispatching.
> 
> You should be able to end up with an API that looks something like this:
> 
> from methodurl import methodurl
> 
> urlpatterns = patterns('',
> methodurl(
> url('/objects/$', app.views.create_object, methods=['post', 
> 'put'], name='create_object'),
> url('/objects/$', app.views.list_objects, methods=['get'], 
> name='list_objects'),
> )
> )
> 
> Personally, I'm not particular convinced on the merits of method based 
> routing, but that's not really the issue.
> The important point is that this is something that you should be able to do 
> without needing to modify anything in core Django.
> 
> Regards,
> 
>   Tom
> 
> On Saturday, 13 April 2013 22:48:44 UTC+1, Brantley Harris wrote:
> There's a line in the django URL Dispatcher documentation that is pretty 
> weird:
> 
> 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.
> 
> Well, why?  Most modern web frameworks allow you to specify the method in the 
> routing configuration, Django seems to be an exception in this respect.
> 
> It would be extremely easy to implement, and would lead to vastly better code 
> across new projects, including a simpler way of writing rest style interfaces:
> 
> url('^objects/$', 'views.create_object', methods=['post', 'put'], 
> name='create_object'),
> url('^objects/$', 'views.get_objects', name='list_objects'),
> 
> This has come up many times before and been swatted 

Re: Request method in urls.py

2013-04-15 Thread Alex Ogier
The problem I have with fallthrough-based dispatch is that it encourages
really expensive performance-killing patterns, where you end up doing a
linear scan over view functions round-tripping to the database for each one
to see if the view can handle the request. multiurl is sort of nice because
it least it's obvious that what it's doing might be expensive, and the
whole linear scan is collected in one place so if it gets too long it looks
"wrong" in a Joel Spolsky sense.

I think what's really needed is a mechanism for more intelligent dispatch
decisions. The machinery is there in principle, and django-multiurl takes
advantage of it, but there's a bottleneck which is that in order for a view
to be correctly registered as a URL resolver with reversal, you have to go
through the narrow waist of the url() factory function. This means that
while multiurl is able to pretend to be like include() and delegate to its
child URL resolvers (which I think is what makes reverse() work), it can't
really add intelligence to its view dispatch, it can only sit on the
outside watching responses/catching specific errors, and you end up with N
copies of the regex (though perhaps this is actually a good thing, since it
means you can pass different arguments to different views).

So for example, if you wanted to implement your own intelligent dispatch
function, you are forced to go digging into the internals to find things
like the fact that kwargs passed to the url() function end up as the
default_kwargs attribute on RegexURLResolver instances. Maybe the best
option is to ask Jacob to extend multiurl to support arbitrary dispatch
mechanisms that work in *front* of the URL resolver instead of behind it,
maybe via a callback in multiurl. The following looks like it would be just
as easily added to multiurl as to core, and not that much more onerous:

from multiurl import multiurl, method_dispatch

urlpatterns = patterns('',
multiurl(
url('^objects/$', 'views.create_object', methods=['post',
'put'], name='create_object'),
url('^objects/$', 'views.get_objects', name='list_objects'),
dispatch = method_dispatch
)
)

You might even convince Jacob to make multiurl do a lot of intelligent
things with those kwargs for free (no callback required). For example just
have it filter the views it tries to only the set that matches the HTTP
method if given. There's probably other types of dispatch that are
naturally expressed as properties of the URL object once you allow multiple
URL objects per regex, such as dispatching by the Accept or Accept-Language
headers. All of this stuff falls under multiurl's purview, at least if and
until core supports fallthrough URLs.

Best,
Alex Ogier


On Mon, Apr 15, 2013 at 7:54 AM, Tom Christie wrote:

> This proposal is actually *very* similar to the 'URL
> dispatcher fall-though' 
> threadthat
>  came up recently.
>
> I don't think it'd take much adjustment to take Jacob's django-multiurl
> project  and adapt it to
> deal with method-based dispatching rather than fall-through based
> dispatching.
>
> You should be able to end up with an API that looks something like this:
>
> from methodurl import methodurl
>
> urlpatterns = patterns('',
> methodurl(
> url('/objects/$', app.views.create_object, methods=['post',
> 'put'], name='create_object'),
> url('/objects/$', app.views.list_objects, methods=['get'],
> name='list_objects'),
> )
> )
>
> Personally, I'm not particular convinced on the merits of method based
> routing, but that's not really the issue.
> The important point is that this is something that you should be able to
> do without needing to modify anything in core Django.
>
> Regards,
>
>   Tom
>
> On Saturday, 13 April 2013 22:48:44 UTC+1, Brantley Harris wrote:
>>
>> There's a line in the django URL Dispatcher documentation that is pretty
>> weird:
>>
>> 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.
>>
>>
>> Well, why?  Most modern web frameworks allow you to specify the method in
>> the routing configuration, Django seems to be an exception in this respect.
>>
>> It would be extremely easy to implement, and would lead to vastly better
>> code across new projects, including a simpler way of writing rest style
>> interfaces:
>>
>> url('^objects/$', 'views.create_object', methods=['post', 'put'],
>> name='create_object'),
>> url('^objects/$', 'views.get_objects', name='list_objects'),
>>
>>
>> This has come up many times before and been swatted down for various
>> reasons.  One is that it could be implemented with a one-off dispatcher, as
>> in:
>>
>> url('^objects/$', create_or_list(list=get_**objects,
>> 

Re: Request method in urls.py

2013-04-15 Thread Tom Christie
This proposal is actually *very* similar to the 'URL 
dispatcher fall-though' 
threadthat
 came up recently.

I don't think it'd take much adjustment to take Jacob's django-multiurl 
project  and adapt it to deal 
with method-based dispatching rather than fall-through based dispatching.

You should be able to end up with an API that looks something like this:

from methodurl import methodurl

urlpatterns = patterns('',
methodurl(
url('/objects/$', app.views.create_object, methods=['post', 
'put'], name='create_object'),
url('/objects/$', app.views.list_objects, methods=['get'], 
name='list_objects'),
)
)

Personally, I'm not particular convinced on the merits of method based 
routing, but that's not really the issue.
The important point is that this is something that you should be able to do 
without needing to modify anything in core Django.

Regards,

  Tom

On Saturday, 13 April 2013 22:48:44 UTC+1, Brantley Harris wrote:
>
> There's a line in the django URL Dispatcher documentation that is pretty 
> weird:
>
> 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.
>
>
> Well, why?  Most modern web frameworks allow you to specify the method in 
> the routing configuration, Django seems to be an exception in this respect.
>
> It would be extremely easy to implement, and would lead to vastly better 
> code across new projects, including a simpler way of writing rest style 
> interfaces:
>
> url('^objects/$', 'views.create_object', methods=['post', 'put'], 
> name='create_object'),
> url('^objects/$', 'views.get_objects', name='list_objects'),
>
>
> This has come up many times before and been swatted down for various 
> reasons.  One is that it could be implemented with a one-off dispatcher, as 
> in:
>
> url('^objects/$', create_or_list(list=get_objects, create=create_object), 
> name='create_or_list_objects')
>
>
> But this is overly complex for what should be a simple configuration, 
> forces one to create the same name for the url, and worse, creates a level 
> of indirection breaking the abstraction up; or in other words you're trying 
> to do route configuration, why not do it in the place you're already doing 
> route configuration?
>
> The other argument is that you can do this with Class Based Views.  I 
> don't believe this is a good argument as one would have to utilize Class 
> Based Views to get this basic functionality.  In fact CBV's, only really 
> solve two common issues, one is the boilerplate inherit in forms, and the 
> other method routing.  But the proposed solution to method routing is 
> simpler and better.
>
> I will gladly implement the code required for this, but don't wish to do 
> so if it's going to be quashed, which is why I bring it up here.
>
> Thanks
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-15 Thread Luke Plant
On 15/04/13 10:21, Aymeric Augustin wrote:

> Django already has a syntax for that :
> 
> from django.conf.urls import *
> from django.views.decorators.http import *
> 
> urlpatterns = patterns('',
> url(require_GET(view_that_only_accepts_get), name='accept-get'),
> url(require_POST(view_that_only_accepts_post), name='accept-post'),
> url(require_http_methods(['OPTIONS',
> 'DELETE'])(err_why_would_you_do_that), name='accept-options-delete'),
> )
> 
> https://docs.djangoproject.com/en/dev/topics/http/decorators/#allowed-http-methods

This doesn't work if you want the same URL - the first one will match,
and return a 405 if the method isn't allowed, so you will never fall
through to the next one with the same URL where the method is allowed.

(Unless the URL dispatcher has started doing something very different
from what I what I expect it to do).

Luke

-- 
 A mosquito cried out in pain:
 "A chemist has poisoned my brain!"
 The cause of his sorrow
 was para-dichloro-
 diphenyltrichloroethane

Luke Plant || http://lukeplant.me.uk/

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-15 Thread Łukasz Langa
On 15 kwi 2013, at 11:21, Aymeric Augustin  
wrote:

> Not every feature has to be supported via keyword arguments in the URLconf. 
> Many are expressed through decorators.
> 
> The URL dispatcher might have been designed differently in the first place, 
> but the current version appears to work quite well and I'm not convinced we 
> need to change it in this regard. Make that a -0!

Well, updating the documentation would solve the issue IMHO. Does that work for 
you, Brantley?

-- 
Best regards,
Łukasz Langa

WWW: http://lukasz.langa.pl/
Twitter: @llanga
IRC: ambv on #python-dev

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-15 Thread Aymeric Augustin
2013/4/15 Alex Ogier 

> I agree, I think there are use cases for both types of dispatch, and it
> seems clean and well-defined to make a route that is valid for only a
> subset of HTTP methods. I guess there are a few corner cases to think
> about, for example should Django's url resolver start returning 405s
> instead of 404s when it's just the method that doesn't match? But that kind
> of stuff is easily worked out. I like the syntax too, a list passed as a
> kwarg to the url() function. So +1 from me.
>

Django already has a syntax for that :

from django.conf.urls import *
from django.views.decorators.http import *

urlpatterns = patterns('',
url(require_GET(view_that_only_accepts_get), name='accept-get'),
url(require_POST(view_that_only_accepts_post), name='accept-post'),
url(require_http_methods(['OPTIONS',
'DELETE'])(err_why_would_you_do_that), name='accept-options-delete'),
)

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

Not every feature has to be supported via keyword arguments in the URLconf.
Many are expressed through decorators.

The URL dispatcher might have been designed differently in the first place,
but the current version appears to work quite well and I'm not convinced we
need to change it in this regard. Make that a -0!

-- 
Aymeric.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-14 Thread Alex Ogier
I agree, I think there are use cases for both types of dispatch, and it
seems clean and well-defined to make a route that is valid for only a
subset of HTTP methods. I guess there are a few corner cases to think
about, for example should Django's url resolver start returning 405s
instead of 404s when it's just the method that doesn't match? But that kind
of stuff is easily worked out. I like the syntax too, a list passed as a
kwarg to the url() function. So +1 from me.


On Sun, Apr 14, 2013 at 4:29 PM, Brantley Harris wrote:

> On Sun, Apr 14, 2013 at 2:40 PM, Luke Plant  wrote:
>
>> One reason for not doing this kind of despatch is that handling for
>>  different HTTP methods often involves a lot of common code. The classic
>> form workflow would become longer, more complicated and/or less DRY if
>> it was implemented using two functions instead of one:
>>
>> https://docs.djangoproject.com/en/dev/topics/forms/#using-a-form-in-a-view
>>
>> So, I would disagree that dispatching on HTTP verb would lead to vastly
>> better code - it could easily make things worse.
>>
>>
> Form handling seems like the only common place that a view would want to
> handle different methods coming in, most of the time it makes much more
> sense to break up the view into one for each HTTP Method.  In essence, what
> we're doing is creating our own mini-dispatch in the view and it's clumsy
> most of the time and leads to less RESTful layouts.
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers?hl=en
> .
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-14 Thread Brantley Harris
On Sun, Apr 14, 2013 at 2:40 PM, Luke Plant  wrote:

> One reason for not doing this kind of despatch is that handling for
> different HTTP methods often involves a lot of common code. The classic
> form workflow would become longer, more complicated and/or less DRY if
> it was implemented using two functions instead of one:
>
> https://docs.djangoproject.com/en/dev/topics/forms/#using-a-form-in-a-view
>
> So, I would disagree that dispatching on HTTP verb would lead to vastly
> better code - it could easily make things worse.
>
>
Form handling seems like the only common place that a view would want to
handle different methods coming in, most of the time it makes much more
sense to break up the view into one for each HTTP Method.  In essence, what
we're doing is creating our own mini-dispatch in the view and it's clumsy
most of the time and leads to less RESTful layouts.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-14 Thread Luke Plant
On 13/04/13 22:48, Brantley Harris wrote:
> There's a line in the django URL Dispatcher documentation that is pretty
> weird:
> 
> 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.
> 
> 
> Well, why?  Most modern web frameworks allow you to specify the method
> in the routing configuration, Django seems to be an exception in this
> respect.
> 
> It would be extremely easy to implement, and would lead to vastly better
> code across new projects, including a simpler way of writing rest style
> interfaces:
> 
> url('^objects/$', 'views.create_object', methods=['post', 'put'],
> name='create_object'),
> url('^objects/$', 'views.get_objects', name='list_objects'),
> 
> 
> This has come up many times before and been swatted down for various
> reasons.  One is that it could be implemented with a one-off dispatcher,
> as in:
> 
> url('^objects/$', create_or_list(list=get_objects,
> create=create_object), name='create_or_list_objects')
> 
> 
> But this is overly complex for what should be a simple configuration,
> forces one to create the same name for the url, and worse, creates a
> level of indirection breaking the abstraction up; or in other words
> you're trying to do route configuration, why not do it in the place
> you're already doing route configuration?
>
> The other argument is that you can do this with Class Based Views.  I
> don't believe this is a good argument as one would have to utilize Class
> Based Views to get this basic functionality.  In fact CBV's, only really
> solve two common issues, one is the boilerplate inherit in forms, and
> the other method routing.  But the proposed solution to method routing
> is simpler and better.

You don't have to use Django's CBVs to get this functionality - you can
write your own, avoiding anything you dislike about them.

One reason for not doing this kind of despatch is that handling for
different HTTP methods often involves a lot of common code. The classic
form workflow would become longer, more complicated and/or less DRY if
it was implemented using two functions instead of one:

https://docs.djangoproject.com/en/dev/topics/forms/#using-a-form-in-a-view

So, I would disagree that dispatching on HTTP verb would lead to vastly
better code - it could easily make things worse.

However, this is not an argument against having the *option* to do
method-name dispatching in the URLconf - I can see that there are valid
use cases for that.

Regards,

Luke

-- 
Environmentalists are much too concerned with planet earth.  Their
geocentric attitude prevents them from seeing the greater picture
-- lots of planets are much worse off than earth is.

Luke Plant || http://lukeplant.me.uk/

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-14 Thread Brantley Harris
On Sun, Apr 14, 2013 at 4:56 AM, Łukasz Langa  wrote:

> On 13 kwi 2013, at 23:48, Brantley Harris  wrote:
>
> > It would be extremely easy to implement
>
> Such a statement suggests that the you didn't really think the problem
> through. Few things are "extremely easy to implement", especially in a
> framework with years of legacy projects in the wild.


Which is why I bring up the idea, to hear if anyone has some gotchas or
implementation advice.


>
> > and would lead to vastly better code across new projects, including a
> simpler way of writing rest style interfaces:
> >
> > url('^objects/$', 'views.create_object', methods=['post', 'put'],
> name='create_object'),
> > url('^objects/$', 'views.get_objects', name='list_objects'),
>
> How would you implement a reverse() variant having this functionality in?
>

Reverse deals only with the url, not the method.  Two names "create_object"
and "list_objects" would now point to the same url.  Of course the urls
could change at some point and the urls could diverge, but since you've
already separated the two views by name, you don't have to do any more work.


> Does get_objects respond to DELETE as well?
>

Yes, it's the fall through, accepts all methods just as a url does in
Django now.


> If create_objects raises Http404, do we continue traversing the urlconf?
> What about reverse() in that case?
>

No, since Django does not do this with any other urls.


>
> > I will gladly implement the code required for this, but don't wish to do
> so if it's going to be quashed, which is why I bring it up here.
>
> Often you can find tricky edge cases and other obstacles only through an
> implementation effort. Realistically, no-one will agree to merge a
> functionality based only on a vague mailing list post. Working code wins
> arguments, as they say. Alternatively, a careful up-front design document
> (this is what the core Python team does with PEPs).
>
>
I've brought the topic up for discussion, I'm not looking to see it
pre-approved for merging.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Request method in urls.py

2013-04-14 Thread Łukasz Langa
On 13 kwi 2013, at 23:48, Brantley Harris  wrote:

> It would be extremely easy to implement

Such a statement suggests that the you didn't really think the problem through. 
Few things are "extremely easy to implement", especially in a framework with 
years of legacy projects in the wild.

> and would lead to vastly better code across new projects, including a simpler 
> way of writing rest style interfaces:
> 
> url('^objects/$', 'views.create_object', methods=['post', 'put'], 
> name='create_object'),
> url('^objects/$', 'views.get_objects', name='list_objects'),

How would you implement a reverse() variant having this functionality in?
Does get_objects respond to DELETE as well?
If create_objects raises Http404, do we continue traversing the urlconf? What 
about reverse() in that case?

> I will gladly implement the code required for this, but don't wish to do so 
> if it's going to be quashed, which is why I bring it up here.

Often you can find tricky edge cases and other obstacles only through an 
implementation effort. Realistically, no-one will agree to merge a 
functionality based only on a vague mailing list post. Working code wins 
arguments, as they say. Alternatively, a careful up-front design document (this 
is what the core Python team does with PEPs).

-- 
Best regards,
Łukasz Langa

WWW: http://lukasz.langa.pl/
Twitter: @llanga
IRC: ambv on #python-dev

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Request method in urls.py

2013-04-13 Thread Brantley Harris
There's a line in the django URL Dispatcher documentation that is pretty 
weird:

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.


Well, why?  Most modern web frameworks allow you to specify the method in 
the routing configuration, Django seems to be an exception in this respect.

It would be extremely easy to implement, and would lead to vastly better 
code across new projects, including a simpler way of writing rest style 
interfaces:

url('^objects/$', 'views.create_object', methods=['post', 'put'], 
name='create_object'),
url('^objects/$', 'views.get_objects', name='list_objects'),


This has come up many times before and been swatted down for various 
reasons.  One is that it could be implemented with a one-off dispatcher, as 
in:

url('^objects/$', create_or_list(list=get_objects, create=create_object), 
name='create_or_list_objects')


But this is overly complex for what should be a simple configuration, 
forces one to create the same name for the url, and worse, creates a level 
of indirection breaking the abstraction up; or in other words you're trying 
to do route configuration, why not do it in the place you're already doing 
route configuration?

The other argument is that you can do this with Class Based Views.  I don't 
believe this is a good argument as one would have to utilize Class Based 
Views to get this basic functionality.  In fact CBV's, only really solve 
two common issues, one is the boilerplate inherit in forms, and the other 
method routing.  But the proposed solution to method routing is simpler and 
better.

I will gladly implement the code required for this, but don't wish to do so 
if it's going to be quashed, which is why I bring it up here.

Thanks

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.