[Django] #20479: Adding the concept predicates in the Django url routing

6 views
Skip to first unread message

Django

unread,
May 22, 2013, 11:25:14 AM5/22/13
to django-...@googlegroups.com
#20479: Adding the concept predicates in the Django url routing
-----------------------------+-------------------------------------
Reporter: rach | Owner: nobody
Type: New feature | Status: new
Component: Core (URLs) | Version: master
Severity: Normal | Keywords: urlresolver, predicates
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------
It's something that I tried to bring back from Pyramid.
It's not as complete because the url routing and view lookup is made in
one step in django.
But that allow to add simple matching rules in the logic of the
UrlResolver

See pull-request : https://github.com/django/django/pull/1199

It includes Code, Doc, Tests.

The motivation behind this feature is being able to have more flexibility
in the way to organize
function based views. And specially getting rid of redundant test.

Use cases:

- Post multi forms on a single views, this allow to match the view which
match when a specific submit is in the request

- Get rid of redundant `if method == 'POST'` in function base view

{{{
#!div style="font-size: 80%"
Code highlighting:
{{{#!python

url_pattern += url('/', my_view_GET)
url_pattern += url('/', my_view_POST)

#Decorator to make a urls match only if the predicates return True

predicate_GET = lambda request: request.method == 'GET'
predicate_POST = lambda request: request.method == 'POST'

@url_predicates([predicate_GET])
def my_view_GET(request):
# I can assume now that only GET requests get match to the url
# associated to this view
# ...

@url_predicates([predicate_POST])
def my_view_POST(request):
# I can assume now that only POST requests get match to the
url
# associated to this view
# ...

}}}
}}}

....

The implementation is probably imperfect let me know your feedbacks.
But I hope that could end with a more flexible and powerful routing in
Django.

The Pyramid documentation illustrate very well the configuration
possibility of predicates :
http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/viewconfig.html
#predicate-arguments

--
Ticket URL: <https://code.djangoproject.com/ticket/20479>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 22, 2013, 4:32:37 PM5/22/13
to django-...@googlegroups.com
#20479: Adding the concept predicates in the Django url routing
-------------------------------------+-------------------------------------

Reporter: rach | Owner: nobody
Type: New feature | Status: new
Component: Core (URLs) | Version: master
Severity: Normal | Resolution:
Keywords: urlresolver, | Triage Stage:
predicates | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by svisser):

* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0


Comment:

Your given example of method predicates is already present in Django and
can be done with the following decorators:

* `django.views.decorators.http.require_http_methods`
* `django.views.decorators.http.require_GET`
* `django.views.decorators.http.require_POST`
* `django.views.decorators.http.require_safe`

Note that these only consider the value of `request.method`. I think the
request methods are quite a common use case but it may be worth making
this more general (i.e., predicates on `request`).

--
Ticket URL: <https://code.djangoproject.com/ticket/20479#comment:1>

Django

unread,
May 23, 2013, 3:27:50 AM5/23/13
to django-...@googlegroups.com
#20479: Adding the concept predicates in the Django url routing
-------------------------------------+-------------------------------------

Reporter: rach | Owner: nobody
Type: New feature | Status: new
Component: Core (URLs) | Version: master
Severity: Normal | Resolution:
Keywords: urlresolver, | Triage Stage:
predicates | Someday/Maybe
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by mjtamlyn):

* cc: marc.tamlyn@… (added)
* has_patch: 0 => 1
* stage: Unreviewed => Someday/Maybe


Comment:

This seems to me to be another example of "doing different things at the
same url". There are multiple ways to approach this in Django, and no
obvious "correct" answer. Examples:

- Proposed `ViewCollection` in #16213
- Implemented `ViewSet` from DjangoRestFramework
- `ContinueResolving` from https://github.com/jacobian/django-multiurl
- A simple wrapper "view" function which checks the predicates you spoke
about and routes to other functional views appropriately

At the moment it's not clear what the best approach is. In particular, I
don't like this implementation, but I'd like to know more example use
cases of what you're trying to achieve. For splitting by HTTP method the
basic `View` class is already very good at this. For more complex
functionality such as handling multiple forms etc this is currently not so
well determined (especially in the generic views space).

--
Ticket URL: <https://code.djangoproject.com/ticket/20479#comment:2>

Django

unread,
Jul 19, 2013, 12:11:34 PM7/19/13
to django-...@googlegroups.com
#20479: Adding the concept predicates in the Django url routing
-------------------------------------+-------------------------------------

Reporter: rach | Owner: nobody
Type: New feature | Status: new
Component: Core (URLs) | Version: master
Severity: Normal | Resolution:
Keywords: urlresolver, | Triage Stage:
predicates | Someday/Maybe
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by rach):

There is probably a better way to implement it and it's more in
implementation to illustrate the concept to unloose the relationship
between url routing and view lookup which are only one thing at this stage
in Django.

I m not fan of django-multiurl approach as it add one level of complexity
at the url configuration level, but I agree that could be implemented
following the same technique and wrap the urls into a container. I may
implement it for my next django project.

The usecases are numerous:

- Organize function base view to treat XHR request
- MultiForm submit on a same url
- Build easily api from function base view to handle PUT/POST/GET/DELETE
- create reusable condition to check url arguments without having to write
crazy regexp
- Call specific function base view base contentType
- Not getting a MethodNotAllowed when it's not what you want
- Call a specific view matter if the user is login or not ( ex: / ->
welcom or home)
...

More generics:

- Organize code from function base view and get rid off redundant logic
- Extending function base view without having to follow the Class Base
view model

--
Ticket URL: <https://code.djangoproject.com/ticket/20479#comment:3>

Django

unread,
Jul 23, 2013, 7:23:39 PM7/23/13
to django-...@googlegroups.com
#20479: Adding the concept predicates in the Django url routing
-------------------------------------+-------------------------------------
Reporter: rach | Owner: nobody
Type: New feature | Status: closed

Component: Core (URLs) | Version: master
Severity: Normal | Resolution: wontfix

Keywords: urlresolver, | Triage Stage:
predicates | Someday/Maybe
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by ptone):

* status: new => closed
* resolution: => wontfix


Comment:

I agree with Marc that this particular implementation won't work for
Django. I do think it would be useful to mention the features of HTTP
method dispatching of the View class somewhere in the URLconf docs, and
more generally crystallize the philosophy of Django's core URL mapping,
with some general discussions or links to extend or wrap the logic.

--
Ticket URL: <https://code.djangoproject.com/ticket/20479#comment:4>

Reply all
Reply to author
Forward
0 new messages