0

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.

arlyon
  • 135
  • 1
  • 15
  • I cannot see the `items` presented, can you update your code? – kagami Apr 09 '16 at 23:31
  • The answer @schwobaseggl provided worked really well, but here is the 2nd view. As you can see it follows the template (and I plan on writing classes instead). – arlyon Apr 10 '16 at 07:21

1 Answers1

1

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'
Community
  • 1
  • 1
user2390182
  • 72,016
  • 6
  • 67
  • 89