Je veux appeler une fonction de mon modèle dans un modèle tel que:
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
Et quand je veux appeler cela à partir du modèle: supposez que lors du rendu, je passe channel_status_list comme
channel_status_list = ChannelStatus.objects.all()
{% for i in channel_status_list %}
{{ i.get_related_deltas(3) }}
{% endfor %}
Cela ne fonctionne pas, je peux appeler une fonction qui ne consomme rien, mais ne trouve pas quoi faire si elle a des paramètres
À votre santé
Vous ne pouvez pas appeler une fonction avec des paramètres du modèle. Vous ne pouvez le faire que dans la vue. Vous pouvez également écrire un filtre de modèle personnalisé , qui pourrait ressembler à ceci:
@register.filter
def related_deltas(obj, epk):
return obj.get_related_deltas(epk)
Alors maintenant, vous pouvez le faire dans le modèle:
{% for i in channel_status_list %}
{{ i|related_deltas:3 }}
{% endfor %}
Si la méthode ne nécessite aucun argument, vous pouvez utiliser le décorateur @property et y accéder normalement dans le modèle.
class ChannelStatus(models.Model):
...
@property
def function_you_want_as_property(self):
mystring = ""
...
Pour> 1 argument, utilisez balises simples :
@register.simple_tag
def related_deltas(obj, epk, second_arg):
return obj.get_related_deltas(epk, second_arg)
Modèle:
{% for i in channel_status_list %}
{% related_deltas i 3 4 %}
{% endfor %}
(Notez le changement de syntaxe de {{
à {%
)
Peut prendre des paramètres positionnels (par exemple related_deltas i 3 second_arg=4 debug=true
).
Si vous trouvez qu'il y a trop de propriétés partout ou si vous avez un filtre de modèle pour chaque autre méthode que vous écrivez, une autre solution a été suggérée sur IRC merci @FunkyBob. C'est un peu bien, euh, funky mais c'est sympa dans certains cas.
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)
Une autre option consiste à définir une propriété. Voir http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/ .
Vous écrivez votre fonction qui peut faire à peu près tout ce que vous voulez. Vous en faites une propriété en lecture seule. Vous appelez la propriété à partir du modèle.
Et voilà !!!!