2012-01-20 13 views
18

Mam trochę pętli na stronie i potrzebuję elementu listy w zależności od numeru pętli.Pobierz element listy dynamicznie w szablonach django

Kiedy zadzwonić:

{{ mylist.1 }} 
{{ mylist.2 }} 
{{ mylist.3 }} 

wszystko działa dobrze, ale to, co naprawdę potrzebne jest coś takiego:

{% for x in somenumber|MyCustomRangeTag %} 
    {{ mylist.x }} 
{% endfor %} 

MyCustomRangeTag daje mi Python range() to działa i mam już x jako liczby. Tak więc x to 1, 2, 3 itd. W zależności od numeru pętli. Czy to możliwe i jak?

+0

Czy możesz po prostu przekazać wartości, które potrzebujesz w widoku? jeśli znasz zasięg przed ręką, dlaczego nie podać dokładnie tych wartości, które próbujesz wyświetlić? – dm03514

+0

Nie, nie mogę w tym przypadku. Jest to zakodowana strona niestandardowego koszyka na zakupy, a wszystko to jest częścią niektórych zagnieżdżonych formularzy. – Goran

Odpowiedz

25

Nie jest to możliwe bezpośrednio, ponieważ uważa, że ​​Django "x" jest kluczem do wyszukiwania w mylist - zamiast wartość x. Tak więc, gdy x = 5, Django próbuje wyszukać mylist["x"] zamiast mylist[5].

Poniższa filtr jako rozwiązania:

@register.filter 
def lookup(d, key): 
    return d[key] 

i używać go jak

{{ mylist|lookup:x }} 
+2

Co się stanie, jeśli dane wyjściowe '{{mylist | lookup: x}}' są obiektem i muszę dodatkowo uzyskać dostęp do czegoś? Coś jak 'mylist.1.first_name' – zengr

+2

@zengr Spróbuj' {% z lookup_result = mylist | lookup: x%} {{lookup_result.first_name}} {% endwith%} '. – valid

3

Czy jesteś pewien, że nie można po prostu zrobić:

{% for item in mylist %} 
    {{ item }} 
{% endfor %} 

z filtrem slice, można nawet zrobić kilka dostosowywania.

+0

Myślę, że chcesz mieć '{{item}}' w drugiej linii. Warto również zauważyć, że możesz użyć '{{forloop.counter}}' w pętli, jeśli potrzebujesz jakiegoś indeksu z jakiegoś powodu. – aganders3

+0

Haha, nie martw się. Dzięki za podpowiedź. Właściwie nie byłem zastraszany przez twojego przedstawiciela, po prostu zapomniałem, że jesteśmy w stanie edytować odpowiedzi. To zainspiruje mnie, gdy poczuję się nieśmiały w przyszłości. – aganders3

6

Zauważyłem, że @ e-satis wspomniał, ale myślę, że wbudowana w znacznik plaster szablon zasługuje trochę miłości.

{{ item | slice:"2" }} #gets the third element of the list 
+0

to mogło działać wcześniej, ale dało dobre efekty, gdy dałem mu strzał z django 1.5 – Alvin

+0

To nie działało dla mnie, ale '{{some_list | slice:": 2 "}}' wykonał trik --https : //docs.djangoproject.com/en/1.7/ref/templates/builtins/#slice – Hayden

+0

@Hayden Wierzę, że dostaje tylko pierwsze dwa elementy listy? Zaktualizowałem kod, aby naprawić składnię filtru. –

4

Znacznik przekroju w szablonach Django może wykorzystywać kod podziału Pythona, ale składnia jest wyraźnie inna. Na przykład, jeśli chcesz uzyskać element sekwencji o zmiennej w Pythonie chcesz napisać coś podobnego do poniższego:

>>>mylist = ["0th Element", "1th Element"] 
>>>zero, one = 0, 1 
>>>mylist[zero] 
"0th Element" 
>>>mylist[one] 
"1th Element" 

Używając tej składni z Django kawałek szablonu tagu zwróci listę plasterkach w każdym przypadku, o wątpliwej użyteczności dla uzyskania elementu o znanej index:

{% with "0" as zero %} 
{% with "1" as one %} 
{% with "2" as two %} 

{{mylist|slice:zero}} {{mylist|slice:one}} {{mylist|slice:two}} 

{% endwith %} 
{% endwith %} 
{% endwith %} 

świadczy na html:

[] ["0th Element"] ["0th Element", "1th Element"] 

zanotować różnice: otrzymujesz re zamiast mylist[x].

Django zapewnia wystarczającą ilość narzędzi do obejścia tego problemu. Pierwsza sztuczka polega na użyciu wyraźnych wycinków, takich jak 0:1 dla twoich indeksów, a następnie |join:"" wynikowej listy w jeden element.Tak:

{% with "0:1" as zero %} 
{{mylist|slice:zero|join:""}} 
{% endwith %} 

Wynik:

0th Element 

Dzieje się to w szczególnie przydatny, gdy trzeba uzyskać dostęp do indeksu pętli dominującej gdy mamy do czynienia ze związkiem iterable wewnątrz pętli dziecka:

{% for parent in parent_loop %} 
    {% cycle "0:1" "1:2" "2:3" as parent_loop_index silent %} 
    {% for child in child_loop %} 
     {{child|slice:parent_loop_index|join:""}} 
    {% endfor %} 
{% endfor %} 

Ukończono tylko części zapasowe, chociaż nie sądzę, by Django wdrożył już osiągnięcia.

+0

Dziękujemy! '| join:" "'! –