Вложенный сериализатор Django выдает мне None для всех полей
Я работаю с Django и djangorestframework (версии 3.2.12 и 3.12.4, соответственно) и столкнулся с проблемой вложенных сериализаторов.
У меня есть модели FantasyLeague и FantasyLeagueSettings. FantasyLeagueSettings имеет FK к FantasyLeague
models.py
class FantasyLeague(models.Model):
name = models.CharField(max_length=100)
managers = models.ManyToManyField(User)
yahoo_league_id = models.CharField(max_length=20, blank=True, null=True)
class FantasyLeagueSettings(models.Model):
league = models.ForeignKey(FantasyLeague, on_delete=models.CASCADE, related_name='settings')
max_teams = models.IntegerField(blank=True, null=True)
num_playoff_teams = models.IntegerField(blank=True, null=True)
playoff_start_week = models.IntegerField(blank=True, null=True)
Я сериализую их следующим образом:
serializers.py
class FantasyLeagueSettingsSerializer(serializers.ModelSerializer):
class Meta:
model = FantasyLeagueSettings
fields = ['max_teams', 'num_playoff_teams', 'playoff_start_week']
class FantasyLeagueSerializer(serializers.ModelSerializer):
managers = UserSerializer(read_only=True, many=True)
settings = FantasyLeagueSettingsSerializer(many=False, read_only=True)
class Meta:
model = FantasyLeague
fields = ['id', 'name', 'managers', 'settings', 'yahoo_league_id' ]
Но по какой-то причине FantasyLeagueSerializer(league).data
выдает мне значение None для всех полей настроек (хотя данные о настройках существуют)
Тестовый код:
league = FantasyLeague.objects.get(pk=1)
print('🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥')
print(FantasyLeagueSerializer(league).data)
# FantasyLeagueSerializer(league).data: {'id': 1, 'name': 'PLAYING FOR KEEPS', 'managers': [OrderedDict([('id', 1), ('username', 'Smurflo'), ('settings', OrderedDict([('selected_theme', 'kanagawa')])), ('is_staff', True)])], 'settings': OrderedDict([('max_teams', None), ('num_playoff_teams', None), ('playoff_start_week', None)]), 'yahoo_league_id': '461051' }
# Note how all of the settings fields are None
# Even though league.settings clearly has data and FantasyLeagueSettingsSerializer works
print('🎆🎆🎆🎆🎆🎆🎆🎆🎆🎆🎆🎆🎆🎆🎆🎆🎆🎆🎆')
print(FantasyLeagueSettingsSerializer(league.settings.all()[0]).data)
# {'max_teams': 12, 'num_playoff_teams': 6, 'playoff_start_week': 15}
Кто-нибудь знает, что здесь происходит? Что я упускаю?
Думаю, проблема здесь settings = FantasyLeagueSettingsSerializer(many=False, read_only=True)
изменить many=False
на many=True
Причина проблемы кроется в несогласованных отношениях между FantasyLeague
и FantasyLeagueSettings
.
если экземпляры FantasyLeague
могут иметь более одной настройки, то следует изменить many=False
на many=True
в поле settings
сериализатора FantasyLeagueSerializer
.
class FantasyLeagueSerializer(serializers.ModelSerializer):
...
settings = FantasyLeagueSettingsSerializer(many=True, read_only=True)
...
но если экземпляры FantasyLeague
могут иметь не более одной настройки, то в league
model.OneToOneField
следует изменить тип FantasyLeagueSettings
на
class FantasyLeagueSettings(models.Model):
league = models.OneToOneField(FantasyLeague, on_delete=models.CASCADE, related_name='settings')
...