Django # Декоратор render_html # Decorator
Ещё один декоратор по мотивам… :)
Вот “декоратор”:
def render_html(template_name):
def wrapper(func):
@wraps(func)
def inner(request, *args, **kwargs):
result = func(request, *args, **kwargs)
if result.has_key('_redirect'):
return HttpResponseRedirect(result['_redirect'])
else:
return render_to_response(template_name, RequestContext(request, result))
return inner
return wrapper
Вот пример его использования:
def page_edit_handler(request, slug):
page = get_object_or_404(slug=slug)
if request.method == 'POST':
form = PageForm(request.POST, instance=page)
if form.is_valid():
form.save()
return {'_redirect': page.get_absolute_url()}
else:
form = PageForm(instance=page)
return {'form': form}
page_edit_view = render_html('page_edit.html')(page_edit_handler)
Комментарий к примеру: page_edit_handler выдает обычный dict, который обычно попадает в контекст, и выводится как html. Но иногда нужно сделать редирект, тогда возвращается специальный dict, с ключом ‘_redirect’.
Ключ ‘_redirect’ начинается с подчеркивания - такие ключи не работают в контексте, т.е. {{ _redirect }} выдал бы ошибку. И это - на руку нам, потому что можно использовать этот ключ для наших служебных целей, и никому это не должно помешать.
Решение на первый взгляд - хитрое. Но на самом деле - вполне понятное, и если такой подход использовать в проекте, то вьюхи получаются более компактные, что хорошо. В этом и смысл шаманств :)
И комментарий второй - я специально не использовал в примере синтаксис декоратора! Если делать так, как в примере, то у нас остается “неиспорченная” функция page_edit_handler, которая может нам где-нибудь ещё пригодиться :)