简体   繁体   English

减少 django 视图的执行时间

[英]Reduce the execution time of django view

I have a django view which returns all the products of Product model.我有一个 django 视图,它返回产品 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.我只添加了 3500 个产品,服务器需要 40-50 秒才能响应。 I wonder how much time will it take when i will add 100,000 products.我想知道添加 100,000 个产品需要多长时间。 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模型.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 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.我已经在 Google App 引擎标准上部署了网站。 If i increase gunicorn workers, is it going to help?如果我增加 gunicorn 工人,会有帮助吗?

try paginating the response.尝试对响应进行分页。 I think that would be your best bet.我认为那将是你最好的选择。

https://docs.djangoproject.com/en/3.0/topics/pagination/ https://docs.djangoproject.com/en/3.0/topics/pagination/

In your local environment you receive a response in 3 seconds with 400 elements在您的本地环境中,您会在 3 秒内收到包含 400 个元素的响应

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.这种性能与您在 App Engine 中获得的性能非常相似,正如另一个答案中提到的那样,您可以对结果进行分页。

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. 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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM