Reputation: 5531
I have a model,
class Book(models.Model):
name = models.CharField(max_length=300)
pages = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
rating = models.FloatField()
I am ordering Book objects dynamically based on a category, but I want to get the corresponding value as well. For example, when they are sorted I want to show corresponding prices as well.
Doing:
Book.objects.order_by('price').values()
and in template
Book: {{ book }} - Price: {{ book.value.2 }}
works fine. However, I want to chose which field will be sortable during runtime, for example if I want to order by pages, I need to pass book.value.1
. So, the view should pass the field that is sorted. Something like below would solve my problem:
{{ book.{{ sortField }} }}
Django gives an error. how can I solve this? How can I pass the field so that I can use the corresponding value?
Upvotes: 2
Views: 386
Reputation: 22449
A simplified example:
template
<span>Currently ordering by {{ order_by }}</span>
<ul>
<li><a href="?order_by=price">price</a></li>
<li><a href="?order_by=pages">pages</a></li>
</ul>
<ul>
{% for obj in object_list %}
<li><a href="{{ obj.get_absolute_url }}">{{ obj.name }}</a></li>
{% endfor %}
</ul>
views.py
class FooListView(ListView):
allow_ordering_on = ['pk', 'pages', 'price'] # restrictions
order_by = 'pk'
def get(self, request, *args, **kwargs):
order_by = request.GET.get('order_by', self.order_by)
if order_by in self.allow_ordering_on:
self.order_by = order_by
self.object_list = self.model.objects.all().order_by('whatever')
if not allow_empty and len(self.object_list) == 0:
raise Http404(_(u"Empty list and '%(class_name)s.allow_empty' is False.")
% {'class_name': self.__class__.__name__})
context = self.get_context_data(object_list=self.object_list)
return self.render_to_response(context)
else:
return super(FooListView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(FooListView, self).get_context_data(**kwargs)
context['order_by'] = self.order_by
return context
You can override get_context_data
to add a variable for marking current field ordering.
Upvotes: 2
Reputation: 15211
On shell:
books = Book.objects.order_by('price').values()
book = books[0]
print book['price']
So in the template you should be able to loop over books and access the fields:
{% for book in books %}
{{ book.price }}
{% endfor %}
Upvotes: 0