Django rest framework инвертирует сериализаторы
В Django, у меня в models.py модели определены следующим образом :
class foo1(models.Model):
name = models.CharField(max_length=100)
class foo2(models.Model):
name = models.CharField(max_length=100)
....
foo1 = models.ForeignKey(foo1, on_delete=models.SET_NULL, null=True)
class foo3(models.Model):
name = models.CharField(max_length=100)
....
foo2 = models.ForeignKey(foo2, on_delete=models.SET_NULL, null=True)
class foo4(models.Model):
name = models.CharField(max_length=100)
....
foo3 = models.ForeignKey(foo3, on_delete=models.SET_NULL, null=True)
....
и то, что я ожидаю получить, это формат json, подобный этому :
[
{
"id": 1,
"name": "test1",
"foo2": {
"id": 1,
"name": "test1",
"foo3": {
"id": 1,
"name": "test1",
"foo3": {
...
}
},
....
]
Что я пробовал до сих пор, и это дает мне результат, противоположный тому, что я хочу, вот мой serlialize.py :
class NestedFoo1Serializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = '__all__'
class Nestedfoo2Serializer(serializers.ModelSerializer):
foo1= NestedFoo1Serializer(read_only=True)
class Meta:
model = Facility
fields = '__all__'
результат (противоположный тому, что я хочу):
[
{
"id": 1,
"name": "test1",
"foo4": {
"id": 1,
"name": "test1",
"foo3": {
"id": 1,
"name": "test1",
"foo2": {
...
}
},
....
]
и вот мой view.py :
class TreeView(generics.ListAPIView):
serializer_class = NestedFoo4Serializer
queryset = foo4.objects.all()
Хочу узнать, как инвертировать результат
Проблема может быть в ваших отношениях, а не в сериализаторах. Внешние ключи - это отношения "один ко многим", что для моделей вашего примера означает:
foo2 может иметь только один назначенный объект foo1, но многие объекты foo2 могут иметь один и тот же назначенный объект foo1. То же самое происходит между foo2 и foo3, foo3 и foo4 и т.д...
Если это то, что вы хотите, то API можно структурировать следующим образом:
[
{
"id": 1,
"name": "test1",
"foo2": [
{
"id": 1,
"name": "test1",
"foo3": [
{
"id": 1,
"name": "test1",
"foo3": [
...
],
},
{...}
]
},
{...}
]
},
....
]
Просто задайте связанное имя для каждого из отношений (или используйте имя по умолчанию, которое будет "слизанным" именем модели, где определено отношение, с добавлением _set
в конце):
class foo2(models.Model):
name = models.CharField(max_length=100)
....
foo1 = models.ForeignKey(foo1, on_delete=models.SET_NULL, null=True, related_name="foo2s")
И используйте его в своих сериализаторах с этим связанным именем и many=True
:
class foo1Serializer(serializers.ModelSerializer):
foo2s = NestedFoo2Serializer(read_only=True, many=True)
class Meta:
model = foo1
fields = '__all__'
Если вы хотите иметь точную структуру API, как вы предложили в своем вопросе, вы должны либо изменить отношения, так что отношение от foo1
к foo2
определяется в foo1
, либо использовать OneToOneField
вместо этого, что ограничит каждую foo2
модель уникальной foo1
моделью, назначенной ей.