I have defined two models for retailers and items in their stock. Product is defined in another app. I defined two model methods to get and add stock items. Here is the relevant part of the code:
class Retailer(models.Model):
name = models.CharField(max_length=100)
@property
def stock_items(self):
return StockItem.objects.filter(retailer__id=F('id'))
def add_stock_item(self, product_id):
try:
print "Checking if it's already in stock"
self.stock_items.get(product__id=product_id)
print "It's already in stock"
except ObjectDoesNotExist:
try:
print "Adding item to stock"
product = Product.objects.get(pk=product_id)
StockItem.objects.create(retailer=self, product=product)
print "Added to stock"
except Product.DoesNotExist:
print "Such product doesn't exist"
def __unicode__(self):
return self.name
StockItem(models.Model):
retailer = models.ForeignKey(Retailer)
product = models.ForeignKey(Product)
def __unicode__(self):
return "%s - %s %s" % (self.retailer, self.product.brand, self.product)
When I want to use these model methods, something weird happens. They stop working correctly after adding the first item (In these examples, product 1 is 16 GB iPhone and Product 2 is 32 GB iPhone).
First let’s add some products to our stock:
>>> r = Retailer.objects.get(pk=1)
>>> r.stock_items
[]
>>> r.add_stock_item(1)
Checking if it's already in stock
Adding item to stock
Added to stock
>>> r.add_stock_item(2)
Checking if it's already in stock
Adding item to stock
Added to stock
So far so good. Now let’s try adding products again to see how it handles errors:
>>> r.add_stock_item(1)
Checking if it's already in stock
It's already in stock
>>> r.add_stock_item(2)
Checking if it's already in stock
Adding item to stock
Added to stock
What? Why did it add product 2 again. It was supposed to show a message similar to product 1. Let’s see our stock:
>>> r.stock_items
[<StockItem: hh - Apple iPhone 4S 16GB>]
What happened to product 2? Did it fail to add it to database?
[<StockItem: hh - Apple iPhone 4S 16GB>, <StockItem: hh - Apple iPhone 4S 32GB>, <StockItem: hh - Apple iPhone 4S 32GB>]
Apparently not. It was added to database, but somehow our program fails to check it correctly. Only the first product added to stock is shown by calling r.stock_items. Restarting shell doesn’t change the situation either, so I guess the reason couldn’t be because of when the function is evaluated.
Why does this happen and how can I fix it?
Try to remove
@propertyand change the method to this: