2011-07-01 8 views
6

Tengo 3 diseños diferentes de páginas de productos que me gustaría mostrar dependiendo de la información disponible sobre los productos. Usando el cruce tengo una clase llamada ProductFinder que capta toda la información. Por ejemplo, el usuario va al dominio/verde/pequeño y ProductFinder enumerará todos los productos de mi base de datos que son verdes y pequeños. Esta lista es self.products en la clase ProductFinder. En mi __init__.py he añadido la línea:En Pyramid, ¿cómo puedo usar un renderizador diferente según el contenido del contexto?

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

en products.py que tengo:

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

Sobre la base de lo que está en context.products aunque me gustaría rendir un marrajo diferente. En los pilones que yo hubiera 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 hacer que una plantilla diferente, basado en el contenido de mi contexto?

+0

Su primera línea allí "config.add_view ('app.views.products', name = '')" es muy probablemente * no * lo que desea. El @view_config es el único que creo que realmente te importa aquí. –

Respuesta

10

Comenzaré diciendo que este tipo de cosas parecen tener cuidado en su plantilla.

Sin embargo,, puede influir en qué renderizador se utiliza como parte de la búsqueda de la vista en cualquier forma que desee. Como ya sabrá, puede usar el mismo controlador de vista para múltiples 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) 

NB. Algunas personas podrían estar más interesadas en el enfoque render_to_response aquí porque entonces no confiarán en custom_predicates. ¡Pero por supuesto depende de usted!

@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 Pirámide ignorará los procesadores si su vista devuelve un Response(), que es exactamente lo que hace render_to_response.

+0

muchas gracias. Los predicados personalizados eran exactamente lo que estaba buscando – jchysk

3

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

Si solo se trata de una forma diferente de mostrar sus productos en función de la cantidad, debe tomar la decisión en la plantilla.

+0

¡Buena solución simple! – Lee

Cuestiones relacionadas