Hellnar
Hellnar

Reputation: 64883

Django, updating from model

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

Answers (4)

quiet_penguin
quiet_penguin

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

speakman
speakman

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

istruble
istruble

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

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799310

Modify the appropriate fields then call save() on the instance.

Upvotes: 3

Related Questions