python - template - sistema de plantilla django, llamando a una función dentro de un modelo
python code in template django (5)
No puede llamar a una función con parámetros de la plantilla. Solo puedes hacer esto en la vista. Alternativamente, podría escribir un filtro de plantilla personalizado , que podría verse así:
@register.filter
def related_deltas(obj, epk):
return obj.get_related_deltas(epk)
Entonces ahora puedes hacer esto en la plantilla:
{% for i in channel_status_list %}
{{ i|related_deltas:3 }}
{% endfor %}
Quiero llamar a una función de mi modelo en una plantilla como:
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 esto desde la plantilla: asumir durante la representación, 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, puedo llamar a una función que no consume nada, pero no puedo encontrar qué hacer si tiene un parámetro (s)
Aclamaciones
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 prácticamente todo lo que quieras. Lo convierte en una propiedad de solo lectura. Llama a la propiedad desde la plantilla.
Et voilà !!!!
Para> 1 argumento, use etiquetas simples :
@register.simple_tag
def related_deltas(obj, epk, second_arg):
return obj.get_related_deltas(epk, second_arg)
Modelo:
{% for i in channel_status_list %}
{% related_deltas i 3 4 %}
{% endfor %}
(Tenga en cuenta el cambio de sintaxis de {{
a {%
)
Puede tomar parámetros posicionales (por ejemplo, related_deltas i 3 second_arg=4 debug=true
).
Si el método no requiere ningún argumento, puede usar el decorador @property y acceder a él normalmente en la plantilla.
class ChannelStatus(models.Model):
...
@property
def function_you_want_as_property(self):
mystring = ""
...
Si encuentra que hay demasiadas propiedades corriendo por todos lados o que 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)