При отображении таблицы элементов, если значение для поля X не определено, оно отображается как элемент выбора.
Django делает запрос для каждого элемента select, и это может привести к задержкам в больших таблицах.
Как лучше всего сократить количество запросов?
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 %}
Если есть три элемента, будет сделан один запрос для получения 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')
Есть ли способ передать купленный_бай в шаблон?
Или я должен использовать JS; визуализировать поле формы вне цикла и как-то клонировать / дублировать?
--- редактирует ---
Согласно запросу Эндре: 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",)