Python Django-template-reduce for循环重复,reduce sqlite3 db查询
我发现自己在同一组数据中反复循环,多次访问数据库以实现在一个模板上显示正确的数据,代码如下: {item.itemimage_set.all%} {%endfor%} {item.itemimage_set.all%} {%endfor%} {%if item.itemimage_set.count>1%} {%endif%} {item.itemimage_set.all%} {%endfor%} 上面的代码呈现项目的itemimage引导转盘,并在同一页面上呈现一个额外的转盘模式: {item.itemimage_set.all%} {%endfor%} {item.itemimage_set.all%} {%endfor%} {%if item.itemimage_set.count>1%} {%endif%} 数据结构: 类Itemmodels。模型: 名称=。。。等 类ItemImagemodels。模型: item=models.ForeignKeyItem,on_delete=models.CASCADE image=models.ImageFieldupload_to='itemimages',null=True,blank=True 正如您所看到的,模板中有5个forloop循环,这导致频繁地从数据库查询同一组数据。 我所尝试的: 我已尝试将item.itemimage_set.all%}中的{%图像替换为item.load_related_itemimage%}中的{%图像,并在models.py中: 类Itemmodels。模型: 名称=。。。 def load_相关_itemimageself: 返回self.itemimage\u set.prefetch\u相关的'image' 此提示错误: “image”未解析为支持预取的项-这是一个无效的预取参数 实际上,我对django很陌生,不知道如何使用select_related或prefetch_related,但到目前为止,我已经使用了它们,并设法将数据库查询从150减少到30+。我认为,由于上述愚蠢的循环,频率可以进一步降低,正如你所看到的 转发页面的调试工具栏数据:Python Django-template-reduce for循环重复,reduce sqlite3 db查询,python,sql,django,for-loop,django-queryset,Python,Sql,Django,For Loop,Django Queryset,我发现自己在同一组数据中反复循环,多次访问数据库以实现在一个模板上显示正确的数据,代码如下: {item.itemimage_set.all%} {%endfor%} {item.itemimage_set.all%} {%endfor%} {%if item.itemimage_set.count>1%} {%endif%} {item.itemimage_set.all%} {%endfor%} 上面的代码呈现项目的itemimage引导转盘,并在同一页面上呈现一个额外的转盘模式: {ite
SELECT "appname_itemimage"."id",
"appname_itemimage"."item_id",
"appname_itemimage"."image"
FROM "appname_itemimage"
WHERE "appname_itemimage"."item_id" = '19'
5 similar queries. Duplicated 5 times.
5类似的问题。重复5次。坏是不是
view.py
类ItemDetailViewDetailView:
“显示单个项目”
型号=项目
template_name='精品店/item.html'
感谢@Iain Shelvington的回答,他对上述代码的解决方案很有魅力,这个怎么样:
我认为它们是相关的,所以我没有把它们分开来提出另一个问题——如果项目本身在forloop中会怎么样?在这种情况下,如何使用预回迁?谢谢
{subcategory.item_set.all%}
{%endfor%}
因为我需要在循环通过subcategry.item_集时访问item.itemimage_集,这是一个比以前更糟糕的问题,因为它在加载itemimage时会导致19次重复
此模板由ListView呈现
类CategoryListViewListView:
'显示项目列表'
型号=类别
分页方式=1
template\u name='finitery/show\u category.html'
上下文\对象\名称='类别\显示'
def get_querysetself:
qs=super.get\u queryset.get\u categories\u与\u项
self.gender=self.kwargs.get'gender'在上下文中重用
性别
请求=自我请求
获取筛选表单数据
self.category\u selected=request.GET.GET'category\u selected'
self.brand\u selected=request.GET.GET'brand\u selected'
self.min\u price=request.GET.GET'min\u price'
self.max\u price=request.GET.GET'max\u price'
如果性别==‘女性’:
self.gender_number=1
elif性别==“男性”:
self.gender_number=2
其他:
提高Http404
获取\u category\u selected=category.objects.filter
性别=self.gender\u编号、姓名\uuuuuiExact=self.category\u选中。第一个
category_selected_pk=get_category_selected.pk如果get_category_selected,则为get_category_selected.pk,否则为None
get_subcategory_selected=subcategory.objects.filter
类别\性别=self.gender\编号、名称\ iexact=self.category\已选择。第一个
subcategory_selected_pk=get_subcategory_selected.pk如果get_subcategory_selected则为None
category_pk=category_selected_pk如果category_selected_pk else self.kwargs.get
“卡特
奥利_pk'
subcategory_pk=subcategory_selected_pk if subcategory_selected_pk else self.kwargs.get
“子类别_pk”
打印'\nself.kwargs:\n',性别,类别主键,子类别主键
如果性别而非类别而非子类别:
qs=qs.get_categories_by_gendergender
打印“\nCategoryLV\u qs\u gender=”,“\n',qs,”\n',gender,“\n”
返回qs
elif性别和类别主键:
qs=qs.filterpk=category_pk
打印“\nCategoryLV\U qs\U category=”,“\n',qs”,\n'
返回qs
elif性别和子类别_pk:
qs=子类别.objects.annotateCount'item'。排除
项目计数=0。过滤器pk=子类别
self.context\u object\u name='subcategory\u显示'
打印“\nCategoryLV\u qs\u sub\u category=”,“\n”,qs,“\n”
返回qs
def get_validated_catsself:
类别_验证=[]
子类别\u验证=[]
项目\u已验证=[]
所选品牌=自选品牌
最小价格=self.min\u价格
如果最小价格==或最小价格为无:
最低价格=0
最高价格=自身最高价格
如果最大价格==或最大价格为无:
最高价格=999999
对于item.objects中的项,请选择与之相关的“类别”、“子类别”、“标记”。过滤器类别\uuuuuu gender=self.gender\u编号:
如果intmin_price您应该使用与预回迁itemimage_集相关的预回迁,以便每次访问item.itemimage_集时都能得到缓存结果
item = get_object_or_404(Item.objects.prefetch_related('itemimage_set'), pk=pk)
查看详细信息
你能分享你的观点吗?是的,刚刚编辑了这篇文章。感谢您提供了我使用基于类的视图的答案。您能看看底部新附加的代码吗?这是一个更大的问题。非常感谢你!你能分享你想要优化的ListView的代码吗?附在最后。。。但它有点混乱,请随时给我任何你想看的指针或附加代码
class ItemDetailView(DetailView):
model = Item
queryset = Item.objects.prefetch_related('itemimage_set')