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