web-dev-qa-db-fra.com

django système de modèles, appel d'une fonction à l'intérieur d'un modèle

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é

61
crib

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 %}
81
Daniel Roseman

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 = ""
        ...
34
sabalaba

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).

6
laffuste

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)
5
Skylar Saveland

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à !!!!

2
Arnaud Sahuguet