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 <christie....@gmail.com>wrote:

> This proposal is actually *very* similar to the 'URL
> dispatcher fall-though' 
> thread<https://groups.google.com/d/msg/django-developers/64I3Qy4OH-A/RqKv_GCfLREJ>that
>  came up recently.
>
> I don't think it'd take much adjustment to take Jacob's django-multiurl
> project <https://github.com/jacobian/django-multiurl> 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.
>
>
>

-- 
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.


Reply via email to