Как более эффективно сериализовать данные в 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)