使用两个 "Sibling" 模型创建嵌套序列化程序

Creating a Nested Serializer with two "Sibling" Models

我正在尝试获得与此类似的 JSON 输出:

{
    name: John Doe,
    best_buy_price: 420,
    best_sell_price: 69,
    player_profile: {
        tsn_link: https://a_link.com
    }
    playerlistingadvanced: { # This is where I'm having the issue
        sales_minute: 7,
    }
}

我有三个模型。 playerProfile 是“主要”模型,playerListingplayerListingAdvanced 通过一对一的关系连接到 playerProfileplayerPfofile 将有自己的端点,但我还想创建一个主要是列表和高级列表数据的端点(如上所示)。

这是 model.py 文件的精简版:

class PlayerProfile(models.Model):
    card_id = models.CharField(max_length=120, unique=True, primary_key=True)
    name = models.CharField(max_length=420, null=True)
    tsn_link = models.CharField(max_length=420, null=True)
   
 
class PlayerListing(models.Model):
    player_profile = models.OneToOneField(
        PlayerProfile,
        on_delete=models.CASCADE,
        null=True)
    name = models.CharField(max_length=420, null=True)
    best_sell_price = models.IntegerField(null=True)
    best_buy_price = models.IntegerField(null=True)


class PlayerListingAdvanced(models.Model):
    player_profile = models.OneToOneField(
        PlayerProfile,
        on_delete=models.CASCADE,
        null=True)
    sales_minute = models.DecimalField(max_digits=1000, decimal_places=2, null=True)

这是 serializer.py 我已经尝试过,但还没有开始工作。

class PlayerListingAdvancedForNestingSerializer(serializers.ModelSerializer):
    class Meta:
        model = PlayerListingAdvanced
        fields = (
            'sales_minute',
            'last_week_average_buy',
            'last_week_average_sell',
        )

class PlayerListingSerializer(serializers.ModelSerializer):
    player_profile = PlayerProfileForListingSerializer() # works
    playerlistingadvanced = PlayerListingAdvancedForNestingSerializer() #doesn't work
    
    class Meta:
        model = PlayerListing
        fields = (
            'name',
            'best_sell_price',
            'best_buy_price',
            'playerlistingadvanced',
            'player_profile'
        )

我假设因为 playerListing 和 playerListingAdvanced 没有直接关系,所以我需要做一些其他事情来完成这项工作。有人能给我指出正确的方向吗?

您可以使用 SerializerMethodField。你的假设是正确的。试试这个:

class PlayerListingSerializer(serializers.ModelSerializer):
    player_profile = PlayerProfileForListingSerializer()
    playerlistingadvanced = serializers.SerializerMethodField() 

    class Meta:
        model = PlayerListing
        fields = (
            'name',
            'best_sell_price',
            'best_buy_price',
            'playerlistingadvanced',
            'player_profile'
        )

    def get_playerlistingadvanced(self, obj: PlayerListing):
        player_profile = obj.player_profile
        if hasattr(player_profile, 'playerlistingadvanced'):
            serializer = PlayerListingAdvancedForNestingSerializer(instance=player_profile.playerlistingadvanced)
            return serializer.data
        return None