4

render_to improved#

 3 years ago
source link: https://solovyov.net/blog/2008/render-to-improved/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

render_to improved#

[UPD от 12 ночи]

Чуть больше года назад, когда меня окончательно задолбало писать render_to_response c кучей параметров, я себе написал маленький декоратор render_to, который заметно уменьшал количество писанины.

Но вот не так давно обсуждали его в джаббер-конференции [email protected] (кстати, официальная конференция python.com.ua), где появилась идея слегка его проапгрейдить до возможности задавать темплейт из view (когда одна вью может выдавать различные странички). В принципе, идея усложнения декоратора мне не особенно нравится (да и потом, кому надо - может переделать себе, благо несложно), но по размышлении я увидел, что особенного усложнения нету, плюс сохраняется обратная совместимость полностью (что важно, потому как мне есть и где использовать новую фичу, но не очень хочется ломать все вьюхи, использующие старую версию ;).

Однако первая версия, с дополнительным параметром (именем ключа из возвращаемого словаря), имеет явно менее питоновский привкус, чем вариант, предложенный в комментариях. Теперь можно возвращать дополнительно к словарю ещё и имя темплейта, в который он должен отрисовываться:

@render_to('some/thing_detail.html')
def thing_detail(request):
    ...
    return {'obj': obj}, 'other/thing.html'

Есть один небольшой момент: если возвращается тупль, то первый аргумент не проверяется на свою словарность - для определения типа это не нужно, а программист пускай по своим граблям шагает смело. ;)

def render_to(template):
    """
    Decorator for Django views that sends returned dict to render_to_response function
    with given template and RequestContext as context instance.

    If view doesn't return dict then decorator simply returns output.
    Additionally view can return two-tuple, which must contain dict as first
    element and string with template name as second. This string will
    override template name, given as parameter

    Parameters:

     - template: template name to use
    """
    def renderer(func):
        def wrapper(request, *args, **kw):
            output = func(request, *args, **kw)
            if isinstance(output, (list, tuple)):
                return render_to_response(output[1], output[0], RequestContext(request))
            elif isinstance(output, dict):
                return render_to_response(template, output, RequestContext(request))
            return output
        return wrapper
    return renderer

P.S. Явно в этот раз я из всей работы только то и сделал, что в блог написал… Ну да это мелочи, главное - удобно получилось. :-)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK