153

This may be simple, but I looked around and couldn't find an answer. What's the best way to reference a single item in a list from a Django template?

In other words, how do I do the equivalent of {{ data[0] }} within the template language?

user456584
  • 86,427
  • 15
  • 75
  • 107

5 Answers5

259

It looks like {{ data.0 }}. See Variables and lookups.

Mauricio Cortazar
  • 4,049
  • 2
  • 17
  • 27
Mike DeSimone
  • 41,631
  • 10
  • 72
  • 96
  • 64
    The annoying thing is that I can't say `{{ data.foo }}`, where `foo` is a variable with an index value in it and not a property name. – Mike DeSimone Jan 10 '11 at 23:06
  • 1
    If you're willing to create a custom tag, you can do a lot more. Here we're just working with the built-in stuff. – Mike DeSimone Apr 16 '15 at 13:55
  • Link not working anymore, try this one : https://docs.djangoproject.com/en/1.10/ref/templates/api/#variables-and-lookups – Speccy Mar 19 '17 at 15:00
120

A better way: custom template filter: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/

such as get my_list[x] in templates:

in template

{% load index %}
{{ my_list|index:x }}

templatetags/index.py

from django import template
register = template.Library()

@register.filter
def index(indexable, i):
    return indexable[i]

if my_list = [['a','b','c'], ['d','e','f']], you can use {{ my_list|index:x|index:y }} in template to get my_list[x][y]

It works fine with "for"

{{ my_list|index:forloop.counter0 }}

Tested and works well ^_^

Bakuutin
  • 301
  • 1
  • 9
WeizhongTu
  • 6,124
  • 4
  • 37
  • 51
  • 2
    One of the simplest explanations to learn Template Tags' application! – vanguard69 Jul 14 '15 at 21:32
  • 7
    This was great! But with the {{ List|index:x }} format, how do I access values where I would normally use a dot? {{ (List|index:x).name }} obviously does not work. Thank you! – JTFouquier Jun 01 '16 at 17:54
  • Exactly what I was looking for. Thank you! – Grant Bartel Jul 09 '17 at 11:38
  • I have an array in which I'm not sure of the index of my desired value `{% for id in article_details.heading.contents.article_ids %} {% if id.type == 'DOI' %} {{ article_details.heading.contents.article_ids.forloop.counter0.value }} {% endif %} {% endfor %}` – Akin Hwan Aug 16 '18 at 16:07
  • I am iterating trough a list(matches), while iterating i have another list where i want to use the index (counter0), i tried {{ matchTeamEmblems.forloop.counter0.homeTeamID }} but it doesnt work, the matchTeamEmblems is a list i generate in simple_tag which builds an URL(static..) for my emblems but i cant access them – kaya Sep 01 '18 at 13:46
  • 1
    @SuperCode '0' means getting the index which starts from 0, not 1 – WeizhongTu Sep 16 '20 at 06:14
  • Why is this a better way then accesing directly the template loookups for attributes: `data.0` ? In this way you can access it's attributes also: `data.0.some_attribute`. – cristian Oct 07 '20 at 09:15
  • this is the better way I think if you need to get the element index (.0, or .1 or .2 etc) from a template variable like forloop.counter : https://stackoverflow.com/questions/53287022/django-template-access-to-list-item-by-forloop-counter it's true this was not the simpler OP question but well its way more interesting – jerome Apr 30 '21 at 08:26
  • 1
    also, as @JTFouquier asked, you can access element attributes using **with** as explained [here](https://stackoverflow.com/questions/53287022/django-template-access-to-list-item-by-forloop-counter) – jerome Apr 30 '21 at 08:35
26

{{ data.0 }} should work.

Let's say you wrote data.obj django tries data.obj and data.obj(). If they don't work it tries data["obj"]. In your case data[0] can be written as {{ data.0 }}. But I recommend you to pull data[0] in the view and send it as separate variable.

arulmr
  • 8,620
  • 9
  • 54
  • 69
yilmazhuseyin
  • 6,442
  • 4
  • 34
  • 38
2

@jennifer06262016, you can definitely add another filter to return the objects inside a django Queryset.

@register.filter 
def get_item(Queryset):
    return Queryset.your_item_key

In that case, you would type something like this {{ Queryset|index:x|get_item }} into your template to access some dictionary object. It works for me.

0

first make sure that the app contain custom tag function is added to INSTALLED APP follow the instruction below

1 in the main directory app create another directory with name templatetags at the same level as model.py,views.py,urls.py.

2 inside of templatetags directory create init.py and another file with the name of your custom tags, for example: my_tags.py.

MainApp/
    __init__.py
    models.py
    templatetags/
        __init__.py
        my_tags.py
    views.py

in your template you would use the following:

{% load my_tags.py %}

in my_tags.py:

from django import template 
register = template.Library()
@register.filter(name="get")
def get(indexable, i):
    return indexable[i]

in views.py:

number = [0,1,2,3,4,5]

return render(
    "index.html", {"number":number}

)

in index.html:

{% load my_tags %}

{{numer|get:forloop.counter0}}

reference How to create custom template tags and filters

i hope you understand, because ingles not my native language