The Mixin approach for applying permissions to CBV views suffers from 3 issues:
1. you need to read the code to see what permissions are being applied to a View
2. multiple bits of disparate code required to specify, e.g., a simple permission check
3. permissions set on a base class are overridden by permission set on sub-class, unless special care is taken
Here's a nice trick, using only built-in django machinery, apply a decorator intended to decorate a django view function to a CBV view. https://docs.djangoproject.com/en/1.11/topics/class-based-views/intro/#decorating-the-class
This approach works for any function decorators with arguments - simply wrap it in a function that takes the same arguments:
def my_cbv_decorator(*args **kwargs):
return method_decorator(a_view_function_decorator(*args, **kwargs), name='dispatch')
Use your new CBV decorator to decorate View sub-classes:
@my_cbv_decorator('some_parameter')
class MyCBView(django.views.generic.TemplateView):
pass # dispatch method for this view is now wrapped by a_view_function_decorator
Note: you can also pass decorator parameter directly to method_decorator, but wrapping it up like this makes the code read nicer.
Decorator to automagically add placeholders to form widgets. `cls` can be any class derived from `django.forms.Form` or `django.forms.ModelForm`. The field labels are used as value for the placeholder. This will affect all form instances of this class.
* add_placeholders only to forms.TextInput and form.Textarea
* add_placeholders_to_any_field adds placeholders to any field
Usage:
@add_placeholders
class Form(forms.Form):
name = forms.CharField
The name field will render as `<input type="text" placeholder="name">`
Use this template tag to get a paginator showing the first and last two pages w/ adjacent pages using ellipsis.
The `page` parameter is a page of a `Paginator` (typically the first but you can use whichever you want).
In case of 50 pages, while being on the 40th, it'll give you the following iterable of `int`s (with `settings.PAGINATOR_ADJACENT_PAGES = 2`):
`(1, 2, 38, 39, 40, 41, 42, 49, 50) `
You get the idea.
Use :
`@group_required(('toto', 'titi'))`
`def my_view(request):`
`...`
`@group_required('toto')`
`def my_view(request):`
`...`
Note that group_required() also takes an optional login_url parameter
`@group_required('toto', login_url='/loginpage/')`
`def my_view(request):`
`...`
As in the login_required() decorator, login_url defaults to settings.LOGIN_URL.
If the raise_exception parameter is given, the decorator will raise PermissionDenied, prompting the 403 (HTTP Forbidden) view instead of redirecting to the login page.
Such as https://docs.djangoproject.com/en/1.8/topics/auth/default/#the-permission-required-decorator
**Inspired by** : https://github.com/django/django/blob/stable/1.8.x/django/contrib/auth/decorators.py
Requires [line_profiler](https://pypi.python.org/pypi/line_profiler)
pip install line_profiler
Will print profile info into console
@line_profiler
def my_view(request):
context = some_quick_func()
return some_heavy_func(context)
It does not work good when nested, so don't wrap `some_heavy_func`. If you want to profile also some nested call - use `extra_view` parameter:
@line_profiler(extra_view=[some_heavy_func])
def my_view(request):
context = some_quick_func()
return some_heavy_func(context)
It will profile `my_view` and `some_heavy_func`
This is a simple django snippet!
It is the *opposite of @login_required* decorator for Django views
Example
**@not_login_required**
```
def login_page(request):
...
```
@vary_on_user doesn't work properly if your site uses third-party cookies, since the cache key is created from *all* of the cookies in the request header. This decorator caches pages based on the user ID, so it works reliably.
Beware if using Amazon Simple Queue Service to execute Celery tasks which send email messages! Sometimes SQS messages are duplicated which results in multiple copies of the messages being sent. This is a simple decorator which uses a cache backend to prevent the task from executing twice in a specified period. For example:
@task
@execute_once_in(3600*24*7)
def cron_first_week_follow_up():
"""
Send a follow-up email to new users!
"""
pass
For more info see
<http://atodorov.org/blog/2013/12/06/duplicate-amazon-sqs-messages-cause-multiple-emails/>
<http://atodorov.org/blog/2013/12/11/idempotent-django-email-sender-with-amazon-sqs-and-memcache/>
This file includes two Django view decorators `header` and `headers` that provide an easy way to set response headers.
Also, because I have to work with a lot of cross domain requests, I include few shortcuts for convenience to set the Access-Control-Allow-Origin header appropriately.
Sample usage for using decorator
`@json_response(ajax_required=True, login_required=True)`
`def subscribe(request):`
` return {"status":"success"}`
Converts a function returning dict into json response. Does is_ajax check and user authenticated check if set in flags. When function returns HttpResponse does nothing.
@cache(60)
def heavy_computation():
for x in xrange(10000000):
pass # just waste some time`
The result of `heavy_computation` calls will be cached for 60 seconds. This cache decorator does not use the Django cache backend and uses the local memory instead.
This one takes a template path as an argument. Return dictionary with template values from your view. It's simple as:
@render_to_template('posts/post_list.html')
def api_get_all(request):
return {'test': 'testing!'}