Python 在django项目中,迭代两个不同模型的最有效方法是什么

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

我在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.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的每个子序列生成项目。