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 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. 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 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.

Sign up to request clarification or add additional context in comments.

2 Comments

{{ list2.pop.0 }} are you certain this doesn't raise an error like "pop function doesn't have 0 attribute" ?
Tested this, and it worked. See also Ruth's second comment to her question.
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 %}

Comments

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.

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.