Производительность вложенных отношений Django Rest Framework на SerializerMethodField
Я долго искал ответ, но так и не нашел. Ситуация такова: У меня есть 3 модели, определенные следующим образом:
class State(models.Model):
name = models.CharField(max_length=150, null=False)
code = models.CharField(max_length=5, null=False)
class City(models.Model):
name = models.CharField(max_length=150, null=False)
code = models.CharField(max_length=7, null=False)
state = models.ForeignKey(State, related_name='cities', on_delete=models.RESTRICT)
class Home(models.Model):
code = models.CharField(max_length=25, null=False
city = models.ForeignKey(City, related_name='homes', on_delete=models.RESTRICT)
Ответ, который нужен людям по поводу домов, выглядит примерно так
[
{
"code": "10011",
"city": "Municipio 1",
"state": "Departamento 1"
},
{
"code": "10012",
"city": "Municipio 1",
"state": "Departamento 1"
}
]
<
class HomeSerializer(serializers.ModelSerializer):
city = SlugRelatedField(slug_field='name', queryset=City.objects.all())
state = SerializerMethodField()
class Meta:
model = Home
fields = ['code', 'city', 'state']
def get_state(self, obj):
return obj.city.state.nombre
Я смог создать этот ответ, сделав следующее с помощью сериализатора:
Но я не уверен, что это правильный способ сделать это, home
это таблица, которая будет сильно расти (возможно, 1M+ строк), и я думаю, что это решение будет обращаться к базе данных много раз. Теперь я знаю, что могу добавить фильтрацию и пагинацию, но меня беспокоит производительность этого решения. Я также пробовал использовать depth = 2
, но им это не понравилось
Я искал в документации, и примеры (которые действительно хороши) берут только 1 вложенное отношение, так что я действительно потерялся здесь. Спасибо.
Где бы вы ни создавали набор запросов, передаваемый сериализатору, вы должны использовать select_related
для получения связанных данных в одном запросе. Таким образом, при обращении к связанным полям не будет выполняться запрос к БД, поскольку данные уже есть
class HomeList(generics.ListAPIView):
queryset = Home.objects.select_related('city__state')
serializer_class = HomeSerializer