2015-02-28 4 views
0

Je suis en train d'écrire du code pour une application django et j'ai besoin d'un champ de modèle qui vient de la valeur d'autres 2 du même modèle.Override save vs Champ personnalisé dans Django

J'ai créé le champ parce que je veux stocker sa valeur dans de DB et ne pas laisser sa valeur juste comme la logique codée dans les vues/admin. Jusqu'à présent, j'ai stocké toutes les valeurs dans un script de population qui appelait la méthode du modèle avant de l'enregistrer. Le problème auquel je suis confronté est que je ne sais pas comment créer une solution qui peut être appelée à partir du script de population (appelé une activité quotidienne de cron) et de la structure django par défaut (principalement admin et vues). Je souhaite qu'il puisse être édité via le formulaire de changement d'admin mais indirectement (en changeant les 2 autres valeurs) tout en l'affichant si possible.

Dois-je créer un champ personnalisé ou remplacer la méthode d'enregistrement? Est-il possible d'éviter d'attribuer une valeur à un champ lors de sa création? Je pourrais écrire un défaut et un blank = true mais ne m'assurerai pas que la valeur est correcte.

Models.py

class Valores(models.Model): 
    TARIFAS = (
     ('1', '2.0A'), 
     ('2', '2.0DHA'), 
     ('3', '2.0DHS'), 
     # (None, 'Elije una tarifa') 
    ) 

    PERIODO_TAR = (
     ('1', 'Punta'), 
     ('2', 'Valle'), 
     ('3', 'Supervalle'), 
     # (None, 'Elije una tarifa') 
    ) 

    PERIODO_HOR = (
     ('1', '00-01'), 
     ('2', '01-02'), 
     ('3', '02-03'), 
     ('4', '03-04'), 
     ('5', '04-05'), 
     ('6', '05-06'), 
     ('7', '06-07'), 
     ('8', '07-08'), 
     ('9', '08-09'), 
     ('10', '09-10'), 
     ('11', '10-11'), 
     ('12', '11-12'), 
     ('13', '12-13'), 
     ('14', '13-14'), 
     ('15', '14-15'), 
     ('16', '15-16'), 
     ('17', '16-17'), 
     ('18', '17-18'), 
     ('19', '18-19'), 
     ('20', '19-20'), 
     ('21', '20-21'), 
     ('22', '21-22'), 
     ('23', '22-23'), 
     ('24', '23-24'), # (None, 'Elije un periodo horario') 
    ) 

    per_hor = models.IntegerField(
     'periodo horario', 
     choices=PERIODO_HOR 
    ) 
    per_tar = models.IntegerField(
     'periodo tarifario', 
     choices=PERIODO_TAR 
    ) 
    tar = models.IntegerField(
     'tarifa', 
     choices=TARIFAS 
    ) 

    def periodo_tarifario(self): 
     # Devuelve el periodo tarifario 
     if self.tar == 1: 
      return 1 

     elif self.tar == 2: 
      if 12 < self.per_hor < 23: 
       return 1 
      else: 
       return 2 

     elif self.tar == 3: 
      if 1 < self.per_hor < 8: 
       return 3 
      elif 8 < self.per_hor < 14 or self.per_hor == 1 or self.per_hor == 24: 
       return 2 
      else: 
       return 1 
+0

Quelle est la raison pour laquelle vous ne voulez pas laisser la logique codée? Peut-être que cela peut nous aider à mieux comprendre ce dont vous avez besoin. –

+0

Je veux l'afficher sur le site d'administration mais aussi à travers des modèles. Les méthodes peuvent être appelées dans les modèles et dans le site modèle de l'admin mais fieldsets et list_filter dans admin.py ne supportent que les champs, donc je ne peux pas l'afficher sur le formulaire de chage ou le filtre par sa valeur. Addiotionnellement je peux afficher des "noms" (comme des choix) dans certains endroits (admin par exemple) et utiliser sa valeur dans d'autres endroits (dans certains modèles): – XcodeX

Répondre

1

Comment l'utilisation de la structure suivante:

class MyModel(models.Model): 
    A_Field=models.IntegerField() 
    B_Field=models.IntegerField() 
    C_Field=models.IntegerField(null=True, blank=True)#this is the generated field 

    def get_C(self): 
     return self.A_Field+self.B_Field 

    def save(self, force_insert=False, force_update=False): 
     self.C_Field=self.get_C() 
     super(MyModel, self).save(force_insert, force_update) 

Attribution d'une valeur par défaut déjà correcte (par exemple, par défaut = get_C dans la définition du champ) échouera comme A_Field et B_Field n'aura pas de valeur au moment où il est invoqué. Si vous avez besoin que cela soit immédiatement évalué dès que vous changez A et B dans un formulaire, vous devrez utiliser JS pour le faire.

+0

Merci pour votre réponse! Donc, la meilleure façon de générer un champ basé sur une méthode est d'appeler sa méthode en remplaçant le processus d'enregistrement. Je vais l'essayer et rejeter la méthode de la méthode personnalisée. – XcodeX