Reputation: 1431
I have a django view which returns all the products of Product model. Situation is discount is dependent on product as well as user so it has to be calculated every time at runtime. I have added only 3500 products yet and server is taking 40-50 seconds to respond. I wonder how much time will it take when i will add 100,000 products. How can i optimize this?
def apply_discount(product_obj,user_obj):
discount1 = product_obj.brand.discount
try:
discount2 = user_obj.special_discount.all().filter(brand=product_obj.brand.name)[0].discount
except IndexError:
discount2 = 0
total_discount = discount1 + discount2
discount_apply_on = product_obj.brand.discount_on
price= getattr(product_obj, discount_apply_on)
final= round(price - (price*total_discount)/100.00,3)
return (product_obj,price,final,total_discount)
@login_required
def product_list(request):
context = {}
product_qs = Product.objects.all()
product_list = []
for product in product_qs:
discount_applied_product = apply_discount(product,request.user)
product_list.append(discount_applied_product)
context['products'] = product_list
return render(request,"myapp/products.html",context)
models.py
class BrandDiscount(models.Model):
name = models.CharField(max_length=255)
discount_on = models.CharField(max_length=25,default="retail_price")
discount = models.FloatField(default=0)
def __str__(self):
return self.name
class Product(models.Model):
brand = models.ForeignKey(BrandDiscount,on_delete=models.SET_NULL, null=True)
part_number = models.CharField(max_length=255)
description = models.TextField(null=True)
pack_price = models.FloatField(null=True)
units_per_pack = models.IntegerField(null=True)
single_price = models.FloatField(null=True)
retail_price = models.FloatField(null=True)
map_price = models.FloatField(null=True)
jobber_price = models.FloatField(null=True)
upc = models.CharField(max_length=255)
stock = models.IntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
app.yaml
runtime: python37
entrypoint: gunicorn -b :$PORT myProject.wsgi --timeout 120
instance_class: F4
handlers:
- url: /static
static_dir: static/
- url: /.*
secure: always
redirect_http_response_code: 301
script: auto
I have deployed website on Google App engine standard. If i increase gunicorn workers, is it going to help?
Upvotes: 0
Views: 412
Reputation: 4640
In your local environment you receive a response in 3 seconds with 400 elements
If you do the math
(400 items / 3s) = ~ 133 items/s
(4500 items / 133 items/s) = ~ 33.83s
This performance is very similar to what you are getting in App Engine, as was mentioned in the other answer, you could paginate your results.
But also you could send a JSON object with the information of all the elements to the interface and let a JavaScript function draw the elements (instead use render
to draw all your page) as the user needs them.
Upvotes: 1
Reputation: 311
try paginating the response. I think that would be your best bet.
https://docs.djangoproject.com/en/3.0/topics/pagination/
Upvotes: 2