Python 在django项目中,迭代两个不同模型的最有效方法是什么
我在django网站上工作。我的模板中有一个产品页面,其中有多个类别,每个类别下有多个产品。 这些是我的模型。py:Python 在django项目中,迭代两个不同模型的最有效方法是什么,python,django,Python,Django,我在django网站上工作。我的模板中有一个产品页面,其中有多个类别,每个类别下有多个产品。 这些是我的模型。py: class Category(models.Model): type=models.CharField(max_length=30) class Product(models.Model): category = models.ForeignKey(Category, on_delete = models.CASCADE) productid=models
class Category(models.Model):
type=models.CharField(max_length=30)
class Product(models.Model):
category = models.ForeignKey(Category, on_delete = models.CASCADE)
productid=models.CharField(max_length=30)
name=models.CharField(max_length=30)
这是我当前的view.py:
def category(request,sort):
b=""
if sort=="all":
b="timeadded"
elif sort=="new":
b="-timeadded"
context = {
'types' : Category.objects.all(),
'prods': Product.objects.filter().order_by(b),
'cartItems':[],
}
if request.user.is_authenticated:
customer=request.user.customer
order, created=Order.objects.get_or_create(customer=customer, complete=False)
cartItems=order.get_cart_items,
items=order.orderitem_set.all()
context['list_cart'] = order.orderitem_set.values_list('product__id', flat=True)
return render(request,"category.html",context)
此视图考虑产品是否已在客户购物车中。目前,为了展示这些产品,我进行了如下迭代:
{% for type in types %}
{% for product in prods %}
{% if product.type.id == type.id %}}
//Display the details
{% endif %}
{% endfor %}
{% endfor %}
起初,当我没有添加很多产品时,这对我来说效果很好,但现在当我使用大约400个产品进行测试时,加载速度非常慢。原因可能是我正在迭代所有类别的所有产品。请告诉我一个更有效的方法来解决这个问题,同时还要记住产品是否在购物车中,以及如何在我的模板中迭代。
谢谢。您可以先对所有
产品进行FD蚀刻,然后按类型对其进行分组,例如:
from itertools import groupby
from operator import attrgetter
def category(request,sort):
sorting = ['category_id']
if sort == 'all':
sorting.append('timeadded')
elif sort == 'new':
sorting.append('-timeadded')
qs = Product.objects.select_related('category').order_by(*sorting)
types = [
(k, list(vs))
for k, vs in groupby(qs, attrgetter('category'))
]
context = {
'types' : types,
'cartItems':[],
}
if request.user.is_authenticated:
customer=request.user.customer
order, created=Order.objects.get_or_create(customer=customer, complete=False)
cartItems=order.get_cart_items,
items=order.orderitem_set.all()
context['list_cart'] = order.orderitem_set.values_list('product__id', flat=True)
return render(request,"category.html",context)
从itertools导入groupby
从运算符导入吸引器
def类别(请求、排序):
排序=['category_id']
如果排序==“全部”:
sorting.append('timeadded')
elif sort=='new':
sorting.append('-timeadded')
qs=产品。对象。选择相关(“类别”)。按(*排序)排序
类型=[
(k,清单(vs))
对于k,vs在groupby中(qs,attrgetter('category'))
]
上下文={
“类型”:类型,
“cartItems”:[],
}
如果request.user.u经过身份验证:
customer=request.user.customer
订单,已创建=订单.对象.获取或创建(客户=客户,完成=假)
cartItems=order.get\u cart\u items,
items=order.orderitem\u set.all()
上下文['list\u cart']=order.orderitem\u set.values\u list('product\u id',flat=True)
返回呈现(请求“category.html”,上下文)
在模板中,我们可以迭代键值元组:
{% for category, prods in types %}
<b>{{ category.type }}</b>
{% for product in prods %}
{{ product.name }}
{% endfor %}
{% endfor %}
{%类别,产品类型%}
{{category.type}
{prods%中产品的%s}
{{product.name}
{%endfor%}
{%endfor%}
谢谢你的回答。它似乎工作得非常好,但我有一些怀疑。排序=['category_id']做什么。即使参数是任何东西,它也会加载以前没有发生过的站点。此外,最重要的问题是,您的回答是否会影响任何其他功能,如购物车中的产品。另外,由于我是一个初学者,我第一次在你的答案中寻找一些方法,所以你可以简单地解释一下它如何比我的方法更有效。Thanks@VATSALJAIN:它是订购条件的列表。我们首先需要对类别id
(或该类别的某个部分)进行订购,以防止产品
的订购顺序与产品
的“序列”不相同。我发表了我的评论。请注意。Thanks@VATSALJAIN:通常不会改变购物车功能,因为这通常是不同的逻辑。性能增益取决于类别的数量,因为它将O(nm)算法转化为O(n)算法。@VATSALJAIN:是的,我们只扫描一次产品
s的列表,而groupby
将为具有相同类别的产品
s的每个子序列生成项目。