Reputation: 135
I'm making a small site in Django with 'items' and 'characters' in a sqlite database based on the app in the 'first steps' on the documentation page. The tables (currently) follow a similar format so I want to try and make a flexible template. In my views.py, the two views are set up like so:
def characters(request):
sortby = 'lastname'
data_list = Characters.objects.order_by(sortby)
template = loader.get_template('database.html')
context = {
'data_list': data_list,
'directory': 'wiki/characters',
'sortby': sortby,
}
return HttpResponse(template.render(context, request))
def items(request):
sortby = 'name'
data_list = Clothes.objects.order_by(sortby)
template = loader.get_template('database.html')
context = {
'data_list': data_list,
'directory': 'wiki/items',
'sortby': sortby,
}
return HttpResponse(template.render(context, request))
The only difference being the sortby variable and the directory variable. The problem is, I would like to sort the characters by their lastname, and the items by their name. The issue arises in my template, specifically data.sortby:
{% if data_list %}
<ul>
{% for data in data_list %}
<li><a href="{{data.id}}/">{{data.sortby}}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No characters,</p>
{% endif %}
If I manually reference the field I want without brackets it works fine, so I'm sure it's the string causing the issue. How do I sort by the field I specify in views.py?
Thanks in advance from a noob.
Upvotes: 0
Views: 671
Reputation: 73490
You can get an idea in this (a little outdated) answer, but the bottom line is that there is no built-in way to access attributes by name getattr()
-style in django templates. So you would need to write a custom filter, as described in the django docs:
# app/templatetags/attr_tags.py
from django import template
register = template.Library()
@register.filter
def get_attribute(value, arg):
return getattr(value, arg)
Now you can do in your template:
{% load attr_tags %}
# ...
{{ data|get_attribute:sortby }}
# {{ data.sortby }} can't work because that tries to access
# an attribute named 'sortby', not an attribute with the name
# stored in the context variable of the name 'sortby'
Upvotes: 1