| commit 0: | 8a651a47fa3b |
| branch: | default |
| tags: | tip |
13 months ago
Changed (Δ7.9 KB):
djangorators/__init__.py (4 lines added, 0 lines removed)
djangorators/models.py (null-size change)
djangorators/permissions.py (16 lines added, 0 lines removed)
djangorators/related.py (18 lines added, 0 lines removed)
djangorators/rendering.py (15 lines added, 0 lines removed)
examples/djangorators_testproject/__init__.py (null-size change)
examples/djangorators_testproject/manage.py (14 lines added, 0 lines removed)
examples/djangorators_testproject/models.py (9 lines added, 0 lines removed)
examples/djangorators_testproject/settings.py (41 lines added, 0 lines removed)
examples/djangorators_testproject/templates/animals/item.html (1 lines added, 0 lines removed)
examples/djangorators_testproject/templates/animals/list.html (3 lines added, 0 lines removed)
examples/djangorators_testproject/tests.py (47 lines added, 0 lines removed)
examples/djangorators_testproject/urls.py (11 lines added, 0 lines removed)
examples/djangorators_testproject/views.py (57 lines added, 0 lines removed)
Up to file-list djangorators/__init__.py:
1 |
||
2 |
from permissions import owner_required |
|
3 |
from related import from_object, from_queryset |
|
4 |
from rendering import as_html |
Up to file-list djangorators/permissions.py:
1 |
from django.http import HttpResponseNotFound |
|
2 |
||
3 |
def owner_required(func): |
|
4 |
""" |
|
5 |
Warning: depends on from_object's djangorator for the related_* access. |
|
6 |
""" |
|
7 |
def _dec(request, *args, **kwargs): |
|
8 |
if 'related_object' in kwargs: |
|
9 |
if kwargs['related_object'].owner == request.user: |
|
10 |
return func(request, *args, **kwargs) |
|
11 |
elif 'related_queryset' in kwargs: |
|
12 |
kwargs['related_queryset'] = kwargs['related_queryset'].filter(owner=request.user) |
|
13 |
return func(request, *args, **kwargs) |
|
14 |
||
15 |
return HttpResponseNotFound() |
|
16 |
return _dec |
1 |
from django.shortcuts import get_object_or_404 |
|
2 |
||
3 |
def from_object(object_class): |
|
4 |
def wrap(func): |
|
5 |
def _dec(request, *args, **kwargs): |
|
6 |
object_id = kwargs['%s_id' % object_class.__name__.lower()] |
|
7 |
kwargs['related_object'] = get_object_or_404(object_class, id=object_id) |
|
8 |
return func(request, *args, **kwargs) |
|
9 |
return _dec |
|
10 |
return wrap |
|
11 |
||
12 |
def from_queryset(queryset): |
|
13 |
def wrap(func): |
|
14 |
def _dec(request, *args, **kwargs): |
|
15 |
kwargs['related_queryset'] = queryset |
|
16 |
return func(request, *args, **kwargs) |
|
17 |
return _dec |
|
18 |
return wrap |
Up to file-list djangorators/rendering.py:
1 |
from django.views.generic.simple import direct_to_template |
|
2 |
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound |
|
3 |
||
4 |
def as_html(template_name): |
|
5 |
def wrap(func): |
|
6 |
def _dec(request, *args, **kwargs): |
|
7 |
response = func(request, *args, **kwargs) |
|
8 |
# TODO: add more, or even better find an elegant hack :) |
|
9 |
http_responses = (HttpResponse, HttpResponseRedirect, HttpResponseNotFound) |
|
10 |
if isinstance(response, http_responses): |
|
11 |
return response |
|
12 |
# Otherwise, the response is a context which is rendered |
|
13 |
return direct_to_template(request, template_name, response) |
|
14 |
return _dec |
|
15 |
return wrap |
Up to file-list examples/djangorators_testproject/manage.py:
1 |
import sys, os |
|
2 |
sys.path.insert(0, os.path.split(os.path.split(os.getcwd())[0])[0]) |
|
3 |
||
4 |
from django.core.management import execute_manager |
|
5 |
||
6 |
try: |
|
7 |
import settings # Assumed to be in the same directory. |
|
8 |
except ImportError: |
|
9 |
import sys |
|
10 |
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) |
|
11 |
sys.exit(1) |
|
12 |
||
13 |
if __name__ == "__main__": |
|
14 |
execute_manager(settings) |
Up to file-list examples/djangorators_testproject/models.py:
1 |
from django.db import models |
|
2 |
from django.contrib.auth.models import User |
|
3 |
||
4 |
class Animal(models.Model): |
|
5 |
name = models.CharField(max_length=50) |
|
6 |
owner = models.ForeignKey(User) |
|
7 |
||
8 |
def __unicode__(self): |
|
9 |
return u'%s owned by %s' % (self.name, self.owner) |
Up to file-list examples/djangorators_testproject/settings.py:
1 |
import os |
|
2 |
ROOT_PATH = os.path.dirname(__file__) |
|
3 |
||
4 |
TEMPLATE_DEBUG = DEBUG = True |
|
5 |
MANAGERS = ADMINS = () |
|
6 |
DATABASE_ENGINE = 'sqlite3' |
|
7 |
DATABASE_NAME = os.path.join(ROOT_PATH, 'testdb.sqlite') |
|
8 |
||
9 |
TIME_ZONE = 'America/Chicago' |
|
10 |
LANGUAGE_CODE = 'en-us' |
|
11 |
SITE_ID = 1 |
|
12 |
USE_I18N = True |
|
13 |
MEDIA_ROOT = '' |
|
14 |
MEDIA_URL = '' |
|
15 |
ADMIN_MEDIA_PREFIX = '/media/' |
|
16 |
SECRET_KEY = '2+@4vnr#v8e273^+a)g$8%dre^dwcn#d&n#8+l6jk7r#$p&3zk' |
|
17 |
TEMPLATE_LOADERS = ( |
|
18 |
'django.template.loaders.filesystem.load_template_source', |
|
19 |
'django.template.loaders.app_directories.load_template_source', |
|
20 |
) |
|
21 |
TEMPLATE_CONTEXT_PROCESSORS = ( |
|
22 |
"django.core.context_processors.auth", |
|
23 |
"django.core.context_processors.debug", |
|
24 |
"django.core.context_processors.i18n", |
|
25 |
"django.core.context_processors.request", |
|
26 |
) |
|
27 |
MIDDLEWARE_CLASSES = ( |
|
28 |
'django.middleware.common.CommonMiddleware', |
|
29 |
'django.contrib.sessions.middleware.SessionMiddleware', |
|
30 |
'django.contrib.auth.middleware.AuthenticationMiddleware', |
|
31 |
) |
|
32 |
ROOT_URLCONF = 'urls' |
|
33 |
TEMPLATE_DIRS = (os.path.join(ROOT_PATH, 'templates'),) |
|
34 |
INSTALLED_APPS = ( |
|
35 |
'djangorators', |
|
36 |
'djangorators_testproject', |
|
37 |
'django.contrib.auth', |
|
38 |
'django.contrib.admin', |
|
39 |
'django.contrib.contenttypes', |
|
40 |
'django.contrib.sessions', |
|
41 |
) |
Up to file-list examples/djangorators_testproject/templates/animals/item.html:
1 |
{{ animal }} |
Up to file-list examples/djangorators_testproject/templates/animals/list.html:
Up to file-list examples/djangorators_testproject/tests.py:
1 |
r""" |
|
2 |
>>> from django.test.client import Client |
|
3 |
>>> from django.contrib.auth.models import User |
|
4 |
>>> from django.core.urlresolvers import reverse |
|
5 |
>>> from djangorators_testproject.models import Animal |
|
6 |
||
7 |
>>> alice = User.objects.create_user('alice', 'alice@example.org', 'wonderful') |
|
8 |
>>> c = Client() |
|
9 |
>>> c.login(username='alice', password='wonderful') |
|
10 |
True |
|
11 |
||
12 |
>>> cat = Animal.objects.create(name=u"cat", owner=alice) |
|
13 |
>>> response = c.get(reverse('classic_animal_item', args=(cat.id,))) |
|
14 |
>>> response.context['animal'] |
|
15 |
<Animal: cat (updated) owned by alice> |
|
16 |
>>> print response.content |
|
17 |
cat (updated) owned by alice |
|
18 |
<BLANKLINE> |
|
19 |
||
20 |
>>> response = c.get(reverse('decorated_animal_item', args=(cat.id,))) |
|
21 |
>>> response.context['animal'] |
|
22 |
<Animal: cat (updated) (updated) owned by alice> |
|
23 |
>>> print response.content |
|
24 |
cat (updated) (updated) owned by alice |
|
25 |
<BLANKLINE> |
|
26 |
||
27 |
>>> lion = Animal.objects.create(name=u"lion", owner=alice) |
|
28 |
||
29 |
>>> response = c.get(reverse('classic_animal_list')) |
|
30 |
>>> response.context['animals'] |
|
31 |
[<Animal: cat (updated) (updated) owned by alice>] |
|
32 |
>>> print response.content |
|
33 |
<BLANKLINE> |
|
34 |
cat (updated) (updated) owned by alice |
|
35 |
<BLANKLINE> |
|
36 |
<BLANKLINE> |
|
37 |
||
38 |
>>> response = c.get(reverse('decorated_animal_list')) |
|
39 |
>>> response.context['animals'] |
|
40 |
[<Animal: cat (updated) (updated) owned by alice>] |
|
41 |
>>> print response.content |
|
42 |
<BLANKLINE> |
|
43 |
cat (updated) (updated) owned by alice |
|
44 |
<BLANKLINE> |
|
45 |
<BLANKLINE> |
|
46 |
||
47 |
""" |
Up to file-list examples/djangorators_testproject/urls.py:
1 |
from django.conf.urls.defaults import * |
|
2 |
||
3 |
from djangorators_testproject.views import classic_animal_item, classic_animal_list, \ |
|
4 |
decorated_animal_item, decorated_animal_list |
|
5 |
||
6 |
urlpatterns = patterns('', |
|
7 |
url(r'^classic/animals/(?P<animal_id>\d+)/$', classic_animal_item, name='classic_animal_item'), |
|
8 |
url(r'^classic/animals/$', classic_animal_list, name='classic_animal_list'), |
|
9 |
url(r'^decorated/animals/(?P<animal_id>\d+)/$', decorated_animal_item, name='decorated_animal_item'), |
|
10 |
url(r'^decorated/animals/$', decorated_animal_list, name='decorated_animal_list'), |
|
11 |
) |
Up to file-list examples/djangorators_testproject/views.py:
1 |
from django.http import HttpResponseNotFound |
|
2 |
from django.shortcuts import get_object_or_404 |
|
3 |
from django.views.generic.simple import direct_to_template |
|
4 |
||
5 |
from djangorators import from_object, from_queryset, owner_required, as_html |
|
6 |
from djangorators_testproject.models import Animal |
|
7 |
||
8 |
def classic_animal_item(request, animal_id): |
|
9 |
# Retrieve item instance |
|
10 |
animal = get_object_or_404(Animal, id=animal_id) |
|
11 |
||
12 |
# Check permissions |
|
13 |
if animal.owner != request.user: |
|
14 |
return HttpResponseNotFound() |
|
15 |
||
16 |
# Do something useful (isn't it?) |
|
17 |
animal.name = '%s (updated)' % animal.name |
|
18 |
animal.save() |
|
19 |
||
20 |
# Render response |
|
21 |
return direct_to_template(request, 'animals/item.html', locals()) |
|
22 |
||
23 |
@from_object(Animal) |
|
24 |
@owner_required |
|
25 |
@as_html('animals/item.html') |
|
26 |
def decorated_animal_item(request, *args, **kwargs): |
|
27 |
animal = kwargs['related_object'] |
|
28 |
||
29 |
# Only do something useful |
|
30 |
animal.name = '%s (updated)' % animal.name |
|
31 |
animal.save() |
|
32 |
||
33 |
return locals() |
|
34 |
||
35 |
def classic_animal_list(request): |
|
36 |
# Retrieve queryset |
|
37 |
animals = Animal.objects.all() |
|
38 |
||
39 |
# Check permissions |
|
40 |
animals = animals.filter(owner=request.user) |
|
41 |
||
42 |
# Do something useful |
|
43 |
animals = animals.exclude(name=u'lion') |
|
44 |
||
45 |
# Render response |
|
46 |
return direct_to_template(request, 'animals/list.html', locals()) |
|
47 |
||
48 |
@from_queryset(Animal.objects.all()) |
|
49 |
@owner_required |
|
50 |
@as_html('animals/list.html') |
|
51 |
def decorated_animal_list(request, *args, **kwargs): |
|
52 |
animals = kwargs['related_queryset'] |
|
53 |
||
54 |
# Only do something useful |
|
55 |
animals = animals.exclude(name=u'lion') |
|
56 |
||
57 |
return locals() |
