У меня есть простое представление списка API, которое использует сериализатор:
class ListCreateDeploymentView(
generics.ListCreateAPIView
):
permission_classes = (IsAuthenticated,)
renderer_classes = [JSONRenderer]
content_negotiation_class = IgnoreClientContentNegotiation
def get_queryset(self):
queryset = Deployment.objects.all()
return queryset
def list(self, request, version):
queryset = self.get_queryset()
serializer = DeploymentListSerializer(queryset, many=True)
data = serializer.data
return Response(data)
Сериализатор прост:
class DeploymentListSerializer(serializers.ModelSerializer):
class Meta:
model = Deployment
fields = (
'id',
'query',
'config',
'started_at',
'finished_at',
'status',
'project',
)
read_only_fields = (
'id',
'query',
'config',
'started_at',
'finished_at',
'status',
'project',
)
Затем я делаю локальный нагрузочный тест с 10 пользователями и задержкой 1 с Каждое выполнение, поэтому целевое число оборотов в секунду составляет 10 req / s, и через несколько минут вы видите это изображение с явным снижением производительности
Что означает Если я открою 10 вкладок в браузере с ajax запрашивать каждую секунду к этой конечной точке, что сервер перестанет отвечать на запросы в течение минуты :
Затем я использовал рекомендации от здесь и используется обычный сериализатор только для чтения:
class DeploymentListSerializer(serializers.ModelSerializer):
# commands = CommandListSerializer(read_only=True, many=True)
# clients = ClientSimpleSerializer(read_only=True, many=True)
id = serializers.IntegerField(read_only=True)
query = serializers.CharField(read_only=True)
config = serializers.CharField(read_only=True)
started_at = serializers.DateTimeField(read_only=True)
finished_at = serializers.DateTimeField(read_only=True)
status = serializers.IntegerField(read_only=True)
project = serializers.CharField(read_only=True)
class Meta:
model = Deployment
fields = (
'id',
'query',
'config',
'started_at',
'finished_at',
'status',
'project',
)
Ситуация стала еще хуже: Наконец, если я удалю сериализацию:
def list(self, request, version):
queryset = self.get_queryset()
data = queryset.values(
'id', 'query', 'config', 'started_at', 'finished_at',
'status', 'project'
)
return Response(data)
И снова проведите тот же тест, производительность становится намного лучше (ожидаемой), но также стабильной:
Проблема в том, что мне нужна сериализация, потому что задача немного сложнее и Мне нужно вернуть вложенные объекты, но это уже падает на такой Простой пример.
Что я не так делаю?
UPD: та же плохая картинка, если я использую функциональный вид:
@api_view(['GET'])
def get_deployments(request, version):
queryset = Deployment.objects.all()
serializer = DeploymentCreateSerializer(queryset, many=True)
data = serializer.data
return Response(data)