В Pyramid, как я могу использовать другой рендерер в зависимости от контекста? - PullRequest
7 голосов
/ 02 июля 2011

У меня есть 3 различных макета страницы продукта, которые я хотел бы отобразить в зависимости от информации о продуктах.Используя обход, у меня есть класс с именем ProductFinder, который собирает всю информацию.Например, пользователь переходит к домену / green / small и ProductFinder перечисляет все продукты из моей БД, которые являются зелеными и маленькими.Этот список является self.products в классе ProductFinder.В моем __init__.py я добавил строку:

config.add_view('app.views.products', name='')

В products.py у меня есть:

from pyramid.view import view_config
@view_config(context='app.models.ProductFinder', renderer='productpage.mako')
def products(context, request):
    return dict(page=context)

На основе того, что находится в context.products, хотя я хотел бы сделатьдругой мако.В Pylons я бы сделал что-то вроде:

def products(context, request):
    if len(context.products) == 1:
        return render("oneproduct.mako")
    elif len(context.product) == 2:
        return render("twoproducts.mako")

Так как же я могу отобразить другой шаблон, основанный на содержании моего контекста?

Ответы [ 2 ]

11 голосов
/ 02 июля 2011

Я начну с того, что в вашем шаблоне вы хотите позаботиться о таком виде.

Однако, , вы можете влиять на то, какой рендерер используется как часть просмотра представления практически любым способом, каким вы хотите. Как вы уже знаете, вы можете использовать один и тот же обработчик представления для нескольких представлений, вам просто нужно помочь Pyramid выяснить, какой из них использовать.

Например:

from pyramid.view import view_config

def ProductLengthPredicate(length):
    def check_length(context, request):
        return len(context.products) == length
    return check_length

@view_config(context='app.models.ProductFinder', renderer='oneproduct.mako',
             custom_predicates=(ProductLengthPredicate(1),))
@view_config(context='app.models.ProductFinder', renderer='twoproducts.mako',
             custom_predicates=(ProductLengthPredicate(2),))
@view_config(context='app.models.ProductFinder', renderer='manyproducts.mako')
def products(context, request):
    return dict(page=context)

NB. Некоторые люди могут быть более заинтересованы в подходе render_to_response здесь, потому что тогда они не будут полагаться на custom_predicates. Но это, конечно, зависит от вас!

@view_config(context='app.models.ProductFinder', renderer='manyproducts.mako')
def products(context, request)
    opts = dict(page=context)
    if len(context.products) == 1:
        return render_to_response('oneproduct.mako', opts, request)
    if len(context.products) == 2:
        return render_to_response('twoproducts.mako', opts, request)
    return opts

Это работает, потому что Pyramid будет игнорировать средства визуализации, если ваше представление возвращает Response(), что именно то, что render_to_response делает.

4 голосов
/ 02 июля 2011

Я не уверен, что это хороший путь, но вы, вероятно, могли бы использовать request.override_renderer = 'oneproduct.mako'.

Если это просто другой способ отображения ваших продуктов в зависимости от количества, вам следует принять решение в шаблоне.

...