Django — Saving Arbitrary Data to Model Instances

I kept having troubles with duplicate queries (where the exact same DB query is used more than once in a page view) because I had failed to save the data in the instance.

I had a “Product” model & a “Price” model where one Product can have many prices (QTY discounts).

I had written a quick method to retrieve the base price by filtering the related Price models:
def get_base_price(self):
 return self.price_set.filter(quantity=1)[0]
main_price = property(get_base_price)

But other methods that used “main_price” kept requiring get_base_price to hit the DB again. I didn’t realize that having main_price defined in the model doesn’t save the information in the model. That was what I had intended by doing main_price = property(get_base_price) but was quite a worthless attempt.

Magus helped me out on IRC and I ended up with :

def get_base_price(self):
 if not hasattr(self, 'price'):
   self.price = decimal.Decimal(self.price_set.filter(quantity=1)[0])
  except IndexError:
   return 'no price'
 return self.price
unit_price = property(get_price)

Where if self.price is not set, it queries the database and gets the data. Looks like I previously thought I was saving the data by defining unit_price in the class. Nope!

Something strange that I don’t understand is when referring to the above saved data from another method.

Assuming we set self.price as above, and unit_price = property(get_price) which returns self.price, this doesn’t work:

def some_other_method(self):
 print self.unit_price # doesn't work

While this does:

def some_other_method(self):
 unit_price = self.unit_price
 print unit_price # works

Maybe somebody can enlighten me here on why that is so.

Anyways, thanks to Magus, I’ve lessened some queries and I’m not as reluctant to define model methods that had previously caused duplicates. Great!

Next I’m working on paginating my product views & keeping the query size down.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s