Reputation: 64883
assume I have this little model:
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)
when I try to use this increase_purchases model from shell:
>>> x = Deal.objects.get(id=1)
>>> x.increase_purchases(4)
AttributeError: 'Deal' object has no attribute 'update'
How can I write a proper function to the model so that I can update the selected querys purchases as I want ?
Upvotes: 2
Views: 5803
Reputation: 840
In Django 1.6.2. Encountered this behavior and used a "filter" then update works as expected. For example, Students.objects.select_for_update().filter(id=3).update(score = 10)
Just fyi: Unless you are handling transactions, modifying each field separately using save() might create data inconsistency in a multi-threaded environment. By the time threadA calls save() on a model, another threadB could have changed the model fields and saved. In which case threadA has to read the updated model and change.
Upvotes: 1
Reputation: 966
Or use the += expression for cleaner code:
class Deal(models.Model):
purchase_count = models.IntegerField(default=0)
def purchase(self, quantity=1):
self.purchase_count += quantity
Upvotes: 1
Reputation: 13722
Based on your example and description, you probably want something like this:
class Deal(models.Model):
purchase_count = models.IntegerField(default=0)
def purchase(self, quantity=1):
self.purchase_count = self.purchase_count + quantity
I agree with Ignacio; modify the object and then save it. So in the shell:
> 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()
Yes, I renamed things a little bit in the Deal model. It just seemed more descriptive this way.
Upvotes: 5
Reputation: 799310
Modify the appropriate fields then call save()
on the instance.
Upvotes: 3