6

Is there a way to remove an item from a list in the Django template language?

I have a situation where I'm iterating through one list, and printing the first item in another list. Once the first item is printed I want to remove it from that list.

See below:

{% for item in list1 %}
     {{list2.0}}
     #remove list2.0 from list2
{% endfor %}
4
  • 1
    Do you want to iterate over list excluding some elements? If yes, you can always put if statment inside for loop body. Commented Aug 24, 2012 at 17:28
  • Thanks Konrad, I just edited to include an example of what it is I am trying to do exactly
    – Ruth
    Commented Aug 24, 2012 at 17:33
  • I wouldn't really put the logic in your template. Also, that's a list2 item you're displaying, while looping through list1; is that correct? I think you can use pop inside the template, provided your list is really a list, and not a queryset (otherwise, in your view, do queryset = list(queryset). Then, in your template, try {{ list2.pop }}. I'm also not sure if you can provide an argument to pop, something along the lines of {{ list2.pop|forloop.counter }}. Finally, you could write your own pop tag that does exactly this. I can probably come up with some code for that if you like.
    – user707650
    Commented Aug 24, 2012 at 17:43
  • Thanks everyone for your efforts, as advised it isn't a good idea to remove an item from a list in the Django template language, I'm going to look for another solution, but for anyone who is curious you can indeed use pop to acheive this
    – Ruth
    Commented Aug 24, 2012 at 18:19

4 Answers 4

8

If your list1 and list2 are indeed lists and not querysets, this seems to work:

{{ list2 }}  {# show list2 #}
{% for item in list1 %}
    {{ list2.0 }}
    {# remove list2.0 from list2 #}
    {{ list2.pop.0 }}
{% endfor %}
{{ list2 }}  {# empty #}

Note that pop does not return in this case, so you still need {{ list2.0 }} explicitly.

2
  • {{ list2.pop.0 }} are you certain this doesn't raise an error like "pop function doesn't have 0 attribute" ?
    – jpic
    Commented Aug 24, 2012 at 18:08
  • Tested this, and it worked. See also Ruth's second comment to her question.
    – user707650
    Commented Aug 24, 2012 at 19:43
2

I would try to filter out the item in the view if at all possible. Otherwise you can add in an if or if not statement inside the for loop.

{% for item in list%}
    {% if item.name != "filterme" %}
        {{ item.name }}
    {% endif %}
{% endfor %}
0

You can't delete an item but you can get the list without a certain item (at a constant index)

{% with list2|slice:"1:" as list2 %}
...
{% endwith %}

Of course, nesting rules apply, etc.

In general, I you find yourself doing complex data structure manipulation, just move it to Python - it'd be faster and cleaner.

0

There is no such built-in template tag. I understand that you don't want to print first item of list2 if list1 is not empty. Try:

{% for item in list1 %}
     {{list2.0}}
     ...
{% endfor %}

{% for item in list2 %}
     {% if list1 and forloop.counter == 1 %}
         # probably pass
     {% else %}
         {{ item }}
     {% endif %}
{% endfor %}

This is not a good idea to manipulate the content of the list in templates.

Not the answer you're looking for? Browse other questions tagged or ask your own question.