Reputation: 3963
i am trying to reduce the amount of queries in a Django app, but can't figure out how to do it the right way. I have a model with product all products has a default price, now I have a customerproduct with some customer related product prices
I am open for a redesign ;)
class Product(models.Model)
name = models.CharField(max_length=255)
price = models.DecimalField(default=0, max_digits=12, decimal_places=2)
....
def get_prices(self, customer=None):
'''
get prices for the current product based on the price matrix given by bbp
'''
if customer:
prices = self.get_customer_prices()
if prices:
self.price = self.customerproduct_set.filter(deleted=0).last().price
return self
class CustomerProduct(AbstractProductPrice):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
price = models.DecimalField(default=0, max_digits=12, decimal_places=2)
....
Now i want all products with related customer prices.
products = Product.objects.all().prefetch_related('customerproduct_set')
for product in products:
product.get_prices(customer=1)
Prefetch is not "working" i don't understand how to use it.. please help.
I have 31 products in my db and django_debug_tool result in 35 queries.
Upvotes: 1
Views: 1079
Reputation: 16010
Prefetch CustomerProducts
only for the customer you are interested in, then work with that result. Something like that:
products = Product.objects.all().prefetch_related(
models.Prefetch(
'customerproduct_set',
queryset=CustomerProduct.objects.filter(customer=customer, deleted=0).order_by('id')
to_attr='customer_prices'
)
)
def get_product_prices(product):
customer_prices = getattr(product, 'customer_prices', None)
if customer_prices:
return customer_prices[-1].price
return product.price
for product in products:
print get_product_prices(product)
Upvotes: 2