2010-02-09 7 views
2

suppose que j'ai ce petit modèle:Django, la mise à jour du modèle

class Deal(models.Model): 
    purchases = models.IntegerField(default=0)#amount of purchases so far 

    increase_purchases(self,to_add): 
     self.update(purchases =self.purchases + to_add) 

lorsque je tente d'utiliser ce increase_purchases modèle de shell:

>>> x = Deal.objects.get(id=1) 
>>> x.increase_purchases(4) 
AttributeError: 'Deal' object has no attribute 'update' 

Comment puis-je écrire une fonction propre au modèle pour que je puisse mettre à jour les achats de requêtes sélectionnés comme je veux?

Répondre

3

Sur la base de votre exemple et description, vous voulez probablement quelque chose comme ceci:

class Deal(models.Model):   
    purchase_count = models.IntegerField(default=0) 

    def purchase(self, quantity=1): 
     self.purchase_count = self.purchase_count + quantity 

Je suis d'accord avec Ignacio; modifiez l'objet, puis enregistrez-le. Donc, dans la coquille:

> great_deal = Deal.objects.get(id=1) 
> great_deal.purchase(4) 
> great_deal.save() 
> # or w/o an explicite argument it will record a single purchase 
> # great_deal.purchase() 

Oui, j'ai renommé les choses un peu dans le modèle Deal. Cela semblait juste plus descriptif de cette façon.

1

Modifiez les champs appropriés, puis appelez save() sur l'instance.

+0

mais pour autant que je sache enregistrer enregistrer une nouvelle instance, alors que je veux mettre à jour l'existant. salutations – Hellnar

+0

Il ne créera un nouvel enregistrement que si PK est None ou n'existe pas dans la base de données. Sinon, il mettra à jour l'enregistrement existant avec ledit PK. –

1

Ou utilisez le + = expression pour un code plus propre:

class Deal(models.Model):   
    purchase_count = models.IntegerField(default=0) 

    def purchase(self, quantity=1): 
     self.purchase_count += quantity 
+1

Oui, mais comment faites-vous ce travail dans une situation concurrente où d'autres peuvent faire la même chose? – Alper

1

Dans Django 1.6.2. Rencontré ce comportement et utilisé un "filtre" puis la mise à jour fonctionne comme prévu. Par exemple, Students.objects.select_for_update(). Filter (id = 3) .update (score = 10)

Just fyi: à moins que vous ne gériez des transactions, la modification de chaque champ séparément à l'aide de save() risque de créer une incohérence de données dans un environnement multithread. Au moment où threadA appelle save() sur un modèle, un autre threadB aurait pu changer les champs du modèle et les sauvegarder. Dans ce cas, le threadA doit lire le modèle mis à jour et le modifier.

Questions connexes