In Pyramid, how can I use a different rendering based on context content?

I have 3 different product page layouts that I would like to display based on product information. Using a workaround, I have a class called ProductFinder that captures all the information. For example, a user goes to the domain / green / small, and ProductFinder displays all products from my database that are green and small. This list is self.products in the ProductFinder class. In my __init__.py I added the line:

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

In products.py, I have:

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

Based on that in context. products, although I would like to make another mako. In Pylons, I would do something like:

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

So, how can I render another template based on the contents of my context?

+6
source share
2 answers

I will start by saying that this is similar to what you want to take care of in your template.

However, you can influence which renderer is used as part of the view view almost the way you want. As you already know, you can use the same view handler for several views, you just need to help Pyramid figure out which one to use.

For instance:

 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. Some people may be more interested in render_to_response because then they will not rely on custom_predicates . But that, of course, is up to you!

 @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 

This works because Pyramid will ignore renderers if your view returns Response() , which is what render_to_response does.

+10
source

I'm not sure if this is a good way, but you could use request.override_renderer = 'oneproduct.mako' .

If this is just another way of displaying your products according to quantity, you must make a decision in the template.

+3
source

Source: https://habr.com/ru/post/891848/