gpt4 book ai didi

python - 减少渲染具有相同内联可编辑字段的项目列表的查询数量

转载 作者:太空宇宙 更新时间:2023-11-03 20:59:08 25 4
gpt4 key购买 nike

渲染项目表时,如果未定义字段 X 的值,则会将其渲染为选择元素。

Django 对每个选择元素进行查询,这些查询可能会累加并导致大型表中的延迟。

减少查询数量的最佳方法是什么?

views.py

from rest_framework import renderers
from rest_framework.response import Response

class ItemViewSet(viewsets.ModelViewSet):
queryset = models.Item.objects.select_related("bought_by")
serializer_class= serializers.ItemSerializer
filterset_fields = ("bought_by")
renderer_classes = [renderers.JSONRenderer, renderers.BrowsableAPIRenderer, renderers.TemplateHTMLRenderer]

def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())

if request.accepted_renderer.format == "html":
items = list()
for item in queryset:
items.append({"serializer": self.get_serializer(item), "item": item})


return Response(
{
"items_info": items,
"style": {"template_pack": "rest_framework/inline/"},
},
template_name="myapp/items_list.html",
)
else:
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)

return Response(serializer.data)

items_list.html

{% load static %}
{% load rest_framework %}

{% if items_info %}
{% csrf_token %}

<table id="Items_Table" class="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Active</th>
<th scope="col">Bought By</th>
</tr>
</thead>

<tbody>
{% for pair in items_info %}

<tr scope="row">
<td>{{ pair.item.name }}</td>
<td>{{ pair.item.active }}</td>
<td>
<form action="{{ item.url }}" method="PATCH">
{% render_field pair.serializer.bought_by style=style %}
</form>
</td>
</tr>

{% endfor %}
</tbody>
</table>

{% else %}
<p class="text-center">No items to show.</p>
{% endif %}

如果有3个项目,则每个项目都会进行一次查询以获得serializer.bought_by。我认为 Django/DRF 只会重用该值,但它正在查询每个循环。

尝试在响应中传递 "serializer-bought-by": self.get_serializer().bought_by ,我收到 AttributeError: 'ItemSerializer' object has no attribute'bought_by'

打印我可以看到的序列化器:

>>>print(self.get_serializer())
ItemSerializer(context={'request': <rest_framework.request.Request object>, 'format': None, 'view': <myapp.views.ItemViewSet object>}):
url = HyperlinkedIdentityField(view_name='myapp:item-detail')
name= CharField(unique=True, max_length=50)
active = BooleanField(required=False)
bought_by = SlugRelatedField(allow_null=True, queryset=<QuerySet [<Buyer: James>, <Buyer: John>, ...]>, required=False, slug_field='name')

有没有办法将 buy_by 传递给模板?或者我必须使用JS;在循环之外渲染表单字段并以某种方式克隆/复制?

---编辑---

根据 Endre 的要求:models.py

class Buyer(models.Model):
name = models.CharField(unique=True, max_length = 20)

class Item(models.Model):
name = models.CharField(unique=True, max_length = 50)
active = models.BooleanField(default=True)
bought_by = models.ForeignKey(Buyer, null=True, blank=True, to_field="name",)

最佳答案

您无法直接在序列化器中访问字段的值。您应该使用 serializer.data['bought_by'] 代替。更好的是,不要将序列化器传递给模板,而是传递 serializer.data。至于模板中的查询,不会对数据库进行查询来获取 bought_by,因为它已经包含在序列化器数据中。您仅显示 bought_by 中的一个字段名称,该字段名称已预加载到序列化器数据中。您应用的 select_lated 还可确保在序列化期间不会进行多个查询来获取 bought_by

关于python - 减少渲染具有相同内联可编辑字段的项目列表的查询数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55817818/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com