问题
Every time I code something using Django, I am faced to the same issue (I think this is due to my lack of experience using this framework):
I know how to pass arguments I had from a queryset to a template and how to display it but I don't know how to add argument computed in the view and use them in the template.
Simple View (I master it) : Example: Retrieve a list of Pizzas and display them in a template
views.py
Pizzas = Pizza.objects.all()
return render_to_response( "pizza.html" , {'pizzas':Pizzas} )
pizza.html
{% for pizza in pizzas %}
<li>pizza.name</li>
{% endfor %}
But, let's say I want to add some arguments linked to the queryset but which are not in the database like something I computed in the view, I don't know how to pass this argument to the template and how to use it -> EDIT : I want to order all my pizza by total calories in the template.
Example : For each Pizzas, I have computed the number of calories
views.py
Pizzas = Pizza.objects.all()
tab = []
for pizza in Pizzas:
# Compute some data and return the total number of calories for one pizza
total_number_calories = XXX
tab.append({'p':pizza,'calories':total_number_calories'})
return render_to_response( "pizza.html" , {'pizzas_calories':tab} )
pizza.html
?
I am not even sure my way to pass these additional data to the template is good (creating a table and pass it as an argument to the template.
If you have any idea or best practices to do that in Django I'll take it (and lot of people using Django will do the same !)
回答1:
You should always try and do as much as possible in the view. With the code you've shown, ordering by total calories is just one extra line after the for loop:
tab.sort(key=lambda t: t['calories'])
回答2:
From your view to the template is a one way street; this means that without doing a request back to your view, there is no way to "send data back".
However, while you are in the template you can manipulate objects easily; and this is done using custom template tags and filters
Your template can pass any object that it got from the view to your own filter, and the result of the filter is shown back in the template.
In your case, you can write a filter called caloriecount, with the same logic you would use in the view:
@register.filter
def caloriecount(obj): # Only one argument.
# compute calorie for pizza object
# total_calories =
return total_calories
Then in your template:
{% for pizza in pizzas %}
{{ pizza|caloriecount }}
{% endfor %}
来源:https://stackoverflow.com/questions/12129906/passing-additional-data-to-a-template-in-django