web-dev-qa-db-fra.com

Django - Fonction à l'intérieur d'un modèle. Comment appeler cela depuis une vue?

Je dessine un modèle à Django mais je ne sais pas si c'est le meilleur moyen. J'ai un modèle appelé "Histoire" et à l'intérieur de ce modèle, j'ai une fonction spécialisée qui gérera les insertions de ce modèle.

Alternative 1

class History(models.Model):
    field1 = models.ForeignKey(Request)
    field2 = models.BooleanField()
    field3 = models.DateTimeField()

    def __unicode__(self):
        return str(self.field1.id)

    class Meta: #
        ordering = ['-field3']

    def insert_history(self):
        # Here I will have some business logic to insert the data to the history model

Pour insérer des données dans le modèle d'historique, je devrai toujours utiliser la fonction "insert_history".

Mes questions sont les suivantes:

Le code ci-dessus est correct?

Si oui, comment puis-je appeler "insert_history" depuis une vue?


Alternative 2

J'ai une autre alternative que j'ai testée et cela fonctionne, mais ne se sent pas bien. Le code ressemble à ceci:

class History(models.Model):
    field1 = models.ForeignKey(Request)
    field2 = models.BooleanField()
    field3 = models.DateTimeField()

    def __unicode__(self):
        return str(self.field1.id)

    class Meta: #
        ordering = ['-field3']

def insert_history(field1, field2, field3):
    # Here I will have some business logic to insert the data to the history model

Et je l'appelle d'une vue comme celle-ci:

from app.models import insert_history

insert_history('1', True, 'some_date')

quelle est la bonne façon de le faire? Si l'alternative 1 est correcte, comment puis-je appeler "insert_history" depuis une vue?

Meilleures salutations,

12
André

Est-ce que insert_history utilise self? Ou crée-t-il un nouvel objet d'historique?

Si cela crée un nouvel objet, je le ferais comme ceci:

class History(models.Model):
    @classmethod
    def insert_history(cls, field1, field2, field3):
        # Here be code

L'appeler

from app.models import History
History.insert_history(field1, field2, field3)

BTW, le nom conventionnel pour une méthode créant de nouveaux objets est create. Consultez également https://docs.djangoproject.com/fr/1.9/ref/models/instances/#creating-objects

10
skoll

Je pense qu'il est plus approprié d'utiliser le gestionnaire personnalisé https://docs.djangoproject.com/en/dev/topics/db/managers/ pour ces problèmes.

1
sirfilip

Il suffit de sélectionner votre instance d’historique (par exemple, avec la clé primaire 1):

hist = History.objects.get(pk=1)

... et appelez votre méthode en utilisant la variable hist:

hist.insert_history(...)
1
Steinar Lima

Pour insérer des données dans le modèle d'historique, je devrai toujours utiliser la fonction insert_history.

Oui, cela va définir le champ3, une date-heure, basée sur une logique que j'écrirai dans insert_history

Le moyen le plus simple consiste à remplacer la méthode save :

class History(models.Model):
    field1 = models.ForeignKey(Request)
    field2 = models.BooleanField()
    field3 = models.DateTimeField()

    def __unicode__(self):
        return unicode(self.field1.id) # __unicode__ should return unicode,
                                       # not string.

    class Meta: #
        ordering = ['-field3']

    def save(self, *args, **kwargs):
        self.field3 = your calculated value
        super(History, self).save(*args, **kwargs)

Maintenant, chaque fois que vous enregistrez votre méthode - la valeur de field3 sera le résultat du calcul dans votre méthode de sauvegarde personnalisée. Vous n'avez pas besoin de modifier quoi que ce soit dans vos vues pour que cela fonctionne.

1
Burhan Khalid

Juste pour prolonger la réponse de @burhankhalid, comme je n’étais pas en mesure de commenter en raison d’exigences de représentant assez élevées, j’avais le même besoin de modifier un autre modèle tout en sauvegardant le mien, mais la solution proposée par Burhan Khalid m’a aidé à démarrer.

Le modèle que je devais modifier, j'avais une référence à celle-ci

Ma proposition suppose que Request aurait un 'attrib1' et essaye de sauvegarder la valeur de History.field2

class History(models.Model):
field1 = models.ForeignKey(Request)
field2 = models.BooleanField()
field3 = models.DateTimeField()

def __unicode__(self):
    return unicode(self.field1.id) # __unicode__ should return unicode,
                                   # not string.

class Meta: #
    ordering = ['-field3']

def save(self, *args, **kwargs):
    self.field3 = your calculated value
    self.field1.attrib1 = self.field2  # for instance
    self.field1.save()  # don't forget to save the other 
    super(History, self).save(*args, **kwargs)

Ainsi, le concept de réécriture de la méthode save () et de modification (et sauvegarde) d'autres objets a également fait la différence

0
NKortesmaa