Как более эффективно сериализовать данные в Django Rest Framework?

Ребята, часть моей проблемы решена вопросом: #72534250
Я понял, что путь, по которому я шел, был неправильным, и я должен изменить оптимизацию моделей на сериализаторы и/или viewsets.
Но как?

У меня была такая структура:
*Я уже удалил element_name и element_text из моделей Foo

    class User(models.Model):
        name = models.CharField(max_lenth=50)
        age = models.IntergerField()
    class Customer(models.Model):
        user = models.ForeingKey(User, on_delete=models.CASCADE, verbose_name='User')
    class Element(models.Model):
        name = models.CharField(max_lenth=50)
        text = models.TextField()
        
    class Bar(models.Model):
        element = models.ForeingKey(Element, on_delete=models.CASCADE, verbose_name='Element')
    class Foo(models.Model):
        bar = models.OneToOneField(Bar, on_delete=models.CASCADE, verbose_name='Bar')
        customer = models.ForeingField(Customer, on_delete=models.CASCADE, verbose_name='Customer')
        is_active = models.BooleanField('Is Active', default=False)
        
        def user(self):
            return self.customer.user
        
        # Removed
        def element_name(self):
            return self.bar.element.name

        # Removed
        def element_text(self):
            return self.bar.element.text

И эти сериализаторы:

    class UserSerializer(ModelSerializer):
        class Meta:
            model = User
            fields = '__all__'
    class CustomerSerializer(ModelSerializer):
        class Meta:
            model = Customer
            fields = '__all__'
    class ElementSerializer(ModelSerializer):
        class Meta:
            model = Element
            fields = '__all__'
    class BarSerializer(ModelSerializer):
        element = ElementSerializer()

        class Meta:
            model = Bar
            fields = '__all__'
    class FooSerializer(ModelSerializer):
        bar = BarSerializer()
        user = UserSerializer()
        
        class Meta:
            model = Foo
            fields = '__all__'

И этот набор представлений:

    class FooViewSet(ModelViewSet):
        serializer_class = FooSerializer
        permission_classes = [IsAuthenticated]
        authentication_classes = [JWTAuthentication]
        http_method_names = ['get', 'post', 'patch']

        def get_queryset(self):
           active = self.request.query_params.get('is_active', False)
           name = self.request.query_params.get('name', '')
           data = {'is_active': active}
           if name == 'Fire':
              data['bar__element__name'] = name
           queryset = Foo.objects.filter(**data)
           return queryset
        

Я попробовал этот учебник, но я не заметил никакого реального улучшения производительности. Поэтому я ищу другой способ решения этой проблемы.

Я подумал... Если я просто поставлю select_related(...) в возврат get_queryset, как Django Rest определит, что он должен сериализовать кэшированные данные? Действительно ли это улучшит производительность?

Мне также нужно, чтобы element_name, element_text и объект user были возвращены в GET из FooViewSet. Как я могу вернуть их наиболее эффективным способом?

как Django Rest определит, что он должен сериализовать кэшированных данных? Действительно ли это улучшит производительность?

Все данные, которые были получены select_related, находятся в экземплярах объекта вашей модели. Так как сериализаторы, а также свойства модели, которые вы определили, по существу используют эти экземпляры, они будут иметь доступ к этим "кэшированным" данным напрямую.

Мне также нужно, чтобы в GET FooViewSet возвращались element_name, element_text и object user. Как я могу вернуть их наиболее эффективным способом?

В соответствии с этим, вы можете получить их все в одном запросе (включая то, что нужно element_name и element_text) с помощью:

queryset = Foo.objects.select_related(
    "bar__element",
    "customer__user",
).filter(**data)
Вернуться на верх