2009-07-28 1 views
5

Jak wykonać złożone sortowanie obiektu przed przekazaniem go do szablonu? Na przykład, oto mój widok:Sortowanie i indeksowanie do listy w szablonie Django?

@login_required 
def overview(request): 
    physicians = PhysicianGroup.objects.get(pk=physician_group).physicians 

for physician in physicians.all(): 
    physician.service_patients.order_by('bed__room__unit', 'bed__room__order', 'bed__order') 

return render_to_response('hospitalists/overview.html', RequestContext(request, {'physicians': physicians,})) 

Obiekt lekarzy nie jest prawidłowo uporządkowany w szablonie. Dlaczego nie?

Dodatkowo, w jaki sposób indeksujesz listę wewnątrz szablonu? Na przykład (nie działa):

{% for note_type in note_types %} 
    <div><h3>{{ note_type }}</h3> 
    {% for notes in note_sets.index(parent.forloop.counter0) %} 
    #only want to display the notes of this note_type! 
     {% for note in notes %} 
     <p>{{ note }}</p> 
     {% endfor %} 
    {% endfor %} 
    </div> 
{% endfor %} 

Dzięki kilka, Pete

+0

@Peter Mortensen, dlaczego chodzą usuwania wdzięczność za posty ludzi? Zobacz swoją poprawkę nr 8 tego pytania. Nie uważam tego za akceptowalną. – slypete

Odpowiedz

11

Jak powiedzieli inni, oba problemy najlepiej rozwiązać poza szablonem - albo w modelach, albo w widoku. Jedną ze strategii byłoby dodanie metod pomocniczych do odpowiednich klas.

Pierwsze posortowaną listę pacjentów lekarza za:

class Physician(Model): 
    ... 
    def sorted_patients(self): 
     return self.patients.order_by('bed__room__unit', 
            'bed__room__order', 
            'bed__order') 

I w szablonie, użyj physician.sorted_patients zamiast physician.patients.

"Wyświetlaj nuty tego note_type", wydaje się, że możesz chcieć użyć metody notes dla klasy note_type. Z Twojego opisu nie jestem pewien, czy jest to model klasy, czy nie, ale zasada jest ta sama:

class NoteType: 
    ... 
    def notes(self): 
     return <calculate note set> 

A potem szablon:

{% for note_type in note_types %} 
    <div><h3>{{ note_type }}</h3></div> 
    {% for note in note_type.notes %} 
     <p>{{ note }}</p> 
    {% endfor %} 
    </div> 
{% endfor %} 
+0

Dzięki, trochę trudniej mi zrozumieć, że prawie nic nie da się zrobić w szablonie!Nawet indeksowania do listy! – slypete

+0

W najnowszych wersjach django możesz * indeksować * do listy. –

4

"Chciałbym to zrobić z poziomu szablonu:"

Nie . Zrób to w funkcji widoku, do której należy.

Ponieważ pytanie jest niekompletne, niemożliwe jest zgadnięcie modelu danych i podanie dokładnego rozwiązania.

results= physician.patients.order_by('bed__room__unit', 'bed__room__order', 'bed__order') 

Powinno wystarczyć. Podaj results do szablonu do renderowania. Jest w odpowiedniej kolejności.

Jeśli to nie jest właściwe sortowanie (być może z powodu jakiegoś modelu subtelnie), to zawsze masz taką alternatywę.

def by_unit_room_bed(patient): 
    return patient.bed.room.unit, patient.bed.room.order, patient.bed.order 

patient_list = list(physician.patients) 
patient_list.sort(key=by_unit_room_bed) 

Podaj patient_list do szablonu do renderowania. Jest w odpowiedniej kolejności.

„Jak Ci indeks do listy wewnątrz szablonu”

Nie jestem pewien, co próbujesz zrobić, ale przez większość czasu, odpowiedź brzmi „nie”. Zrób to w funkcji widoku.

Szablon po prostu przechodzi przez proste listy wypełniające proste szablony HTML.

Jeśli wydaje się zbyt skomplikowany dla szablonu, jest. Zachowaj prosty szablon - to tylko prezentacja. Przetwarzanie idzie w funkcji widoku

+0

Jak proponuje się sortowanie obiektów w obiekcie przed przekazaniem go do widoku? Na przykład to nie działa: physician.service_patients = physician.service_patients.all(). Order_by ("bed__room__unit", "bed__room__order", "bed__order") – slypete

+0

Co masz na myśli "nie działa". Co robi źle? –

+0

Przypisanie czyni obiekt bezużytecznym, ponieważ service_patients jest ForeignKey. – slypete

1

powinien być w stanie skonstruować zamówioną zapytanie ustawić w widoku i przekazać je do szablonu:

def myview(request): 
    patients = Physician.patients.order_by('bed__room__unit', 
              'bed__room__order', 
              'bed__order') 
    return render_to_response('some_template.html', 
           dict(patients=patients), 
           mimetype='text/html') 

Szablon można następnie pętli nad patients który będzie zawierał zamawiać wyniki. Czy to nie działa?

EDYCJA: W celu zindeksowania, po prostu użyj składni kropki: mylist.3 w szablonie staje się mylist[3] w python. Aby uzyskać więcej informacji, patrz http://docs.djangoproject.com/en/dev/ref/templates/api/#rendering-a-context.

+0

Nie, nie, odkąd przechodzę w zestawie lekarzy do szablonu. Czy możliwe jest posortowanie każdego pacjenta Lekarza w zestawie lekarzy przed przekazaniem go do szablonu? – slypete

+0

Myślę, że mógłbym przekazać zestaw lekarza i listę uporządkowanych zestawów pacjentów, ale to nie jest w porządku ... jeśli wiesz co mam na myśli. Raczej po prostu przekazuję w jednym zestawie i pomyślałem, że po prostu nie wiem jak to zrobić. – slypete

+0

Zakładałem, że lekarz był modelem, a pacjenci byli menedżerami modeli. Sądzę, że możesz stworzyć metodę instancji na lekarza: get_patients, która właśnie zwraca zestaw zapytań zamówionych pacjentów. Powinieneś być w stanie wywołać to w szablonie i powtórzyć po zestawie wyników. – ars

0

Jest to jeden sposób to zrobić , choć bardzo brzydki:

{% for note in note_sets|slice:"forloop.counter0"|first %}

+0

Niestety, to nie działa. Wypróbowałem to. –

+0

lol, to jest paskudne. – slypete