2009-08-26 10 views
55

Quiero llamar a una función desde mi modelo en una plantilla como:sistema de plantillas de Django, llamando a una función dentro de un modelo

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   

Y cuando quiero llamar a esto de la plantilla: asumen la vez que resulta , paso channel_status_list como

channel_status_list = ChannelStatus.objects.all() 

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

Esto no funciona, estoy en condiciones de llamar a una función que consume nada, pero couln't encontrar qué hacer si tiene parámetro (s)

Cheers

Respuesta

77

No se puede invocar una función con parámetros de la plantilla. Solo puedes hacer esto en la vista. Alternativamente, usted podría escribir un custom template filter, lo que podría tener este aspecto:

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

Así que ahora usted puede hacer esto en la plantilla:

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

hola, muchas gracias por la copia de seguridad! Me aparece el error "related_deltas requires 1 arguments, 0 provided". Estoy haciendo exactamente lo que dijiste. Saludos –

+0

Hmm, eso debería funcionar. ¿Puedes publicar el rastreo completo (probablemente en algún lugar como dpaste.com en lugar de aquí)? –

+0

aquí está: http://dpaste.com/85528/, gracias –

2

Otra opción es definir una propiedad. Ver http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/.

Escribes tu función que puede hacer casi todo lo que quieras. Lo convierte en una propiedad de solo lectura. Llama a la propiedad desde la plantilla.

Et voilà !!!!

+8

esto no tiene sentido ... el sistema de plantillas de Django ya permite llamar a los métodos como si fueran propiedades (siempre que el método no tome ningún argumento) – Anentropic

3

Si encuentra que hay demasiadas propiedades en todas partes o si tiene un filtro de plantilla para cada otro método que escriba, se sugirió otra solución en IRC gracias a @FunkyBob. Está un poco bien, eh, funky pero es bueno en ciertos casos.

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

Si el método no requiere ningún argumento, puede utilizar @property decorator y acceder a él normalmente en la plantilla.

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

que no es el caso en la pregunta, también Django usa propiedades o métodos perfectamente, siempre y cuando no tengan ningún argumento. –

+4

'@ property' no es necesario – laffuste

+0

¿Puede agregar un ejemplo de uso en una plantilla? – ratskin

3

Para> 1 argumento, utilice simple tags:

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

Plantilla:

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

(Tenga en cuenta que el cambio de la sintaxis de {{ a {%)

pueden tomar posicional parámetros (p. related_deltas i 3 second_arg=4 debug=true).

Cuestiones relacionadas