En Pyramid, ¿cómo puedo usar un renderizador diferente basado en el contenido del contexto?

Tengo 3 diseños diferentes de páginas de productos que me gustaría mostrar dependiendo de la información disponible sobre los productos. Utilizando Traversal, tengo una clase llamada ProductFinder que ProductFinder toda la información. Por ejemplo, el usuario va a dominio / verde / pequeño y ProductFinder todos los productos de mi base de datos que sean verdes y pequeños. Esta lista es self.products en la clase ProductFinder . En mi __init__.py he agregado la línea:

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

En products.py tengo:

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

En función de lo que hay en el contexto, aunque los productos me gustaría hacer un mako diferente. En Pylons habría hecho algo como:

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

Entonces, ¿cómo puedo representar una plantilla diferente según el contenido de mi contexto?

    Comenzaré diciendo que este tipo de algo parece ser algo que quiere cuidar en su plantilla.

    Sin embargo , puede influir en qué renderizador se usa como parte de la búsqueda de vista de la forma que desee. Como ya sabe, puede usar el mismo controlador de vista para varias vistas, simplemente necesita ayudar a Pyramid a determinar cuál usar.

    Por ejemplo:

     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) 

    NÓTESE BIEN. Algunas personas podrían estar más interesadas en el enfoque de render_to_response aquí porque entonces no custom_predicates en custom_predicates . ¡Pero por supuesto depende de ti!

     @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 

    Esto funciona porque Pyramid ignorará los renderizadores si su vista devuelve un Response() que es exactamente lo que hace render_to_response .

    No estoy seguro de si es la mejor manera de hacerlo, pero probablemente podrías usar request.override_renderer = 'oneproduct.mako' .

    Si es solo una forma diferente de mostrar sus productos según la cantidad, debe tomar la decisión en la plantilla.