Django # Декоратор для confirm # View decorator for confirmation dialog # confirm_required

Inspired by http://vorushin.ru/blog/26-decorators-python :)

Например, если у меня есть view для удаления чего-нибудь - скажем, файла:

def remove_file(request, id):
    #...

И мне нужно показать страницу с подтверждением удаления - простую “да / нет”. Я написал декоратор, который может работать вот так:

def confirm_context(request, id):
    context = {}
    # ...
    return RequestContext(request, context)

@confirm_required('confirm_remove.html', confirm_context)
def remove_file(request, id):
    #...

Оригинальный view при этом не модифицируется, что радует.

Теперь при вызове view проверяется POST-запрос на наличие в нем ключа “__confirm__”, либо другого - это определяется необязательным параметром декоратора “key”. Если ключа нет - показывается страница подтверждения. Если есть - вызывается оригинальный view.

В шаблон подтверждения передается контекст, созданный функцией “confirm_context”. Это обычная функция, которая принимает те же параметры, что и изначальный view.

Собственно, код декоратора:

def confirm_required(template_name, context_creator, key='__confirm__'):
    def decorator(func):
        def inner(request, *args, **kwargs):
            if request.POST.has_key(key):
                return func(request, *args, **kwargs)
            else:
                context = context_creator and \
                    context_creator(request, *args, **kwargs) \
                    or RequestContext(request)
                return render_to_response(template_name, context)
        return wraps(func)(inner)
    return decorator

ПС. Надо будет подправить верстку блога, а то сниппеты не влезают нормально по ширине.

Notes

  1. rudyryk posted this