| 1 | = Shortcut syntax ideas = |
| 2 | |
| 3 | The Django view system is completely flexible and decoupled from the template system, but that flexibility leads to repetitive code when all you want to do is use Django templates. Let's add a "shortcut" syntax to make it super quick for people to write views. |
| 4 | |
| 5 | This page collects ideas on how shortcut syntax would work. |
| 6 | |
| 7 | == Example == |
| 8 | |
| 9 | Each example on this page does the equivalent of this: |
| 10 | |
| 11 | {{{ |
| 12 | #!python |
| 13 | from django.core.template import Context |
| 14 | from django.core import template_loader |
| 15 | from django.utils.httpwrappers import HttpResponse |
| 16 | |
| 17 | def prime_index(request): |
| 18 | t = template_loader.get_template('primes/index') |
| 19 | c = Context({ |
| 20 | 'title': 'Page Title', |
| 21 | 'primes': [2, 3, 5, 7], |
| 22 | 'header': 'The first 4 primes', |
| 23 | }) |
| 24 | return HttpResponse(t.render(c)) |
| 25 | }}} |
| 26 | |
| 27 | == Idea 1: Decorator == |
| 28 | |
| 29 | {{{ |
| 30 | #!python |
| 31 | from django.views.decorators.shortcuts import page |
| 32 | |
| 33 | @page('primes/index', title='Page Title') # @page(template_name, **default_context) |
| 34 | def prime_index(request): |
| 35 | yield {"primes": [2, 3, 5, 7]} |
| 36 | yield {"header": 'The first 4 primes'} |
| 37 | }}} |
| 38 | |
| 39 | == Idea 2: Class == |
| 40 | |
| 41 | {{{ |
| 42 | #!python |
| 43 | from django.views.templated import TemplatedPage |
| 44 | |
| 45 | class PrimeIndex(TemplatedPage): |
| 46 | def get_context(self, request): |
| 47 | return {'title': 'Page Title', 'primes': [2, 3, 5, 7], 'header': 'The first 4 primes:'} |
| 48 | prime_index = PrimeIndex('primes/index') |
| 49 | }}} |
| 50 | |
| 51 | == Implementations == |
| 52 | |
| 53 | === Idea 1 === |
| 54 | |
| 55 | This goes in django.views.decorators.shortcuts: |
| 56 | |
| 57 | {{{ |
| 58 | #!python |
| 59 | class PageException(Exception): |
| 60 | def __init__(self, arg): |
| 61 | self.arg = arg |
| 62 | |
| 63 | def __call__(self): |
| 64 | pass |
| 65 | |
| 66 | class HttpResponseRedirect(PageException): |
| 67 | def __call__(self): |
| 68 | return httpwrappers.HttpResponseRedirect(self.arg) |
| 69 | |
| 70 | def page(template, **decorator_args): |
| 71 | def _wrapper(fn): |
| 72 | def _innerWrapper(request, **args): |
| 73 | if (template): |
| 74 | tmplt = template_loader.get_template(template) |
| 75 | context_dict = decorator_args.copy() |
| 76 | try: |
| 77 | for i in fn(request, **args): |
| 78 | context_dict.update(i) |
| 79 | context = Context(request, context_dict) |
| 80 | return httpwrappers.HttpResponse(tmplt.render(context)) |
| 81 | except PageException, e: |
| 82 | return e() |
| 83 | |
| 84 | return _innerWrapper |
| 85 | return _wrapper |
| 86 | }}} |
| 87 | |
| 88 | === Idea 2 === |
| 89 | |
| 90 | === Implementation === |
| 91 | |
| 92 | This goes in django.views.templated: |
| 93 | |
| 94 | {{{ |
| 95 | #!python |
| 96 | class TemplatedPage: |
| 97 | def __init__(self, template_name): |
| 98 | self.template_name = template_name |
| 99 | |
| 100 | def __call__(self, *args, **kwargs): |
| 101 | t = template_loader.get_template(self.template_name) |
| 102 | c = Context(self.get_context(*args, **kwargs)) |
| 103 | return HttpResponse(t.render(c)) |
| 104 | }}} |