2009-08-26 18 views
55

chcę wywołać funkcję z mojego modelu w szablonie, takich jak:Django system szablonów, wywoływanie funkcji wewnątrz modelu

class ChannelStatus(models.Model): 
.............................. 
.............................. 

    def get_related_deltas(self,epk): 
     mystring = "" 
     if not self.get_error_code_delta(epk): 
      return mystring 
     else: 
      for i in self.get_listof_outage(): 
       item = i.error_code.all() 
       for x in item: 
        if epk == x.id: 
         mystring= mystring +" "+str(i.delta()) 
     return mystring   

A kiedy chcę zadzwonić to od szablonu: zakładać podczas renderowania mijam channel_status_list jak

channel_status_list = ChannelStatus.objects.all() 

{% for i in channel_status_list %} 
    {{ i.get_related_deltas(3) }} 
{% endfor %} 

ten nie działa, jestem w stanie wywołać funkcję, która pobiera nic, ale nie znaleźli, co zrobić, jeśli ma parametr (y)

Pozdrowienia

Odpowiedz

77

Nie można wywołać funkcji z parametrami z szablonu. Możesz to zrobić tylko w widoku. Alternatywnie można napisać custom template filter, co może wyglądać następująco:

@register.filter 
def related_deltas(obj, epk): 
    return obj.get_related_deltas(epk) 

Więc teraz można to zrobić w szablonie:

{% for i in channel_status_list %} 
    {{ i|related_deltas:3 }} 
{% endfor %} 
+0

Witam, dziękuję za kopię zapasową! Otrzymuję "related_deltas wymaga 1 argumentów, 0 pod warunkiem" błąd. Robię dokładnie tak, jak powiedziałeś. Pozdrowienia –

+0

Hmm, to powinno zadziałać. Czy możesz opublikować pełne informacje zwrotne (prawdopodobnie gdzieś raczej jak dpaste.com niż tutaj)? –

+0

tutaj jest: http://dpaste.com/85528/, dzięki –

2

Inną opcją jest określenie właściwości. Zobacz http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/.

Piszesz swoją funkcję, która może zrobić praktycznie wszystko, co chcesz. Ustawiasz ją jako własność tylko do odczytu. Wywołujesz właściwość z szablonu.

Et voilà !!!!

+8

to jest bezcelowe ... system szablonów Django pozwala już wywoływać metody tak, jakby były właściwościami (o ile metoda nie przyjmuje żadnych argumentów). – Anentropic

3

Jeśli okaże się, że wszędzie jest zbyt wiele właściwości lub masz filtr szablonu dla każdej innej metody, którą piszesz, na IRC zasugerowano inne rozwiązanie dzięki @FunkyBob. Jest trochę dobrze, erm, funky, ale w niektórych przypadkach jest przyjemne.

class MethodProxy(object): 
     """For consolidating into 1 method the calling of methods with various single args 
     (suitable dictionary keys) 

     class MyModel(models.Model): 
      ... 

      def magic(self, value): 
       # Free the ponies 

      def thing(self): 
       return MethodProxy(self.magic) 

     # Usage 
     >>> m = MyModel() 
     ... 
     >>> m.thing['value'] == m.magic('value') 

     # template 
     {{ m.thing.value }} 

     """ 

     def __init__(self, method): 
      self.method = method 
     def __getitem__(self, key): 
      return self.method(key) 
26

Jeśli metoda nie wymaga żadnych argumentów, można skorzystać z dekoratora @property i uzyskać do niego dostęp w szablonie.

class ChannelStatus(models.Model): 
    ... 
    @property 
    def function_you_want_as_property(self): 
     mystring = "" 
     ... 
+2

Co nie jest prawdą w pytaniu, również Django używa właściwości lub metod płynnie, o ile nie mają żadnych argumentów. –

+4

'@ property' not needed – laffuste

+0

Czy możesz dodać przykład użycia w szablonie? – ratskin

3

przez> 1 argumentu użyć simple tags:

@register.simple_tag 
def related_deltas(obj, epk, second_arg): 
    return obj.get_related_deltas(epk, second_arg) 

Szablon:

{% for i in channel_status_list %} 
    {% related_deltas i 3 4 %} 
{% endfor %} 

(Uwaga zmianę składni z {{ do {%)

można wziąć pozycyjny parametry (np. related_deltas i 3 second_arg=4 debug=true).

Powiązane problemy