The rationale behind this decorator is described in django-users google group.
Usage:
=== urls.py ===
urlpatterns = patterns('',
(r'^', include('apps.app1.views')),
(r'^app2', include('apps.app2.views')),
)
=== apps/app1/views/__init__.py ===
@url(r'^index/$')
def index(request):
...
@url(r'^news/$')
def news(request):
...
urlpatterns += include_urlpatterns(r'^members', 'apps.app1.views.members')
=== apps/app1/views/members.py ===
@url(r'^profile/$)
def profile(request):
....
@url(r'^secure/$)
def secure(request):
...
@url(r'^path1/$', '^path2/$') # you can specify several patterns
def multipath_view(request):
...
def helper(): # easily distinguishable - no @url!
...
Summarizing, the benefits are:
* no more creating and supporting urlpattern maps (less files, less code, more DRY)
* have the url associated with a view in-place
* easily see if a function is a view
* fully compatible with other chained decorators
- view
- url
- decorator
- urlpatterns
Here are a couple of Django decorators for limiting access to a view based on the request's `HTTP_REFERER`. Both raise a Django `PermissionDenied` exception if the referer test fails (or a referer simply isn't provided).
The first, `referer_matches_hostname`, takes a hostname (and port, if specified) and matches it against the referer's. If multiple arguments are supplied a match against any of the hostnames will be considered valid.
The second, `referer_matches_re`, takes a regex pattern (like Django's urlpattern) and tests if it matches the referer. This is obviously more flexible than `referer_matches_hostname` providing the ability to match not just the hostname, but any part of the referer url.
Finally there's an simple example decorator, `local_referer_only`, that limits a view to the current site by using Django's `django.contrib.sites` to look up the current hostname.
- view
- referer
- decorator
- http_referer
- request
Sample jQuery javascript to use this view:
$(function(){
$("#id_username, #id_password, #id_password2, #id_email").blur(function(){
var url = "/ajax/validate-registration-form/?field=" + this.name;
var field = this.name;
$.ajax({
url: url, data: $("#registration_form").serialize(),
type: "post", dataType: "json",
success: function (response){
if(response.valid)
{
$("#"+field+"_errors").html("Sounds good");
}
else
{
$("#"+field+"_errors").html(response.errors);
}
}
});
});
});
For each field you will have to put a div/span with id like fieldname_errors where the error message will be shown.
- ajax
- javascript
- view
- generic
- jquery
- validation
- form
Take the legwork out of processing forms.
Most people have a very specific structure to how they process forms in views. If the request method is "GET", then some HTML (with the blank form) is rendered. If the method is "POST", then the form is validated. If the form is invalid, some other HTML is displayed. If valid, the data is submitted and processed in some way.
In order to do this all in a much nicer way, simply subclass `FormHandler`, define three methods (`valid`, `invalid` and `unbound`), point to the form, and use the subclass as your view in the URLconf.
- views
- forms
- view
- form
- view-as-a-class
- formhandler
- form-handler
After using Zope3/Grok for a little, I wondered how hard it would be to implement views as classes in Django, in a similar vain to how it's done in Grok. I came up with something rather simple but effective. It may be more appropriate if you use a template engine other than Django Templates, which allows you to call functions with arguments, but it's still useful none-the-less to encapsulate functions in a class.
You could, for example, extend View to be JinjaView, just replacing render_template().
A nice extension, I imagine, would be to automatically figure out the template name as well as the path prefix for it (since you probably want it to be found under packagename/templatename.html).