Django REST - 无法创建具有关系的模型

时间:2017-01-18 20:07:40

标签: python django rest relationship serializer

我为相关模型创建了一个代码:

class Player(models.Model):
    # Basic
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

    # Enums
    GOALKEEPER = 'GOALKEEPER'
    DEFENDER = 'DEFENDER'
    MIDFIELDER = 'MIDFIELDER'
    FORWARD = 'FORWARD'
    POSITION = (
        (GOALKEEPER, 'Goalkeeper'),
        (DEFENDER, 'Defender'),
        (MIDFIELDER, 'Midfielder'),
        (FORWARD, 'Forward')
    )
    position = models.CharField(max_length=50, choices=POSITION, default=GOALKEEPER)

class PlayerDetail(models.Model):
    # Basic
    height = models.FloatField(default=0.0)
    weight = models.IntegerField(default=0)

    # Relationships
    player = models.ForeignKey(Player, related_name='player_detail')

然后,我为每个模型做了一个序列化器:

class PlayerDetailSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = PlayerDetail
        fields = ('weight', 'height')


class PlayerSerializer(serializers.HyperlinkedModelSerializer):
    player_detail = PlayerDetailSerializer(many=True)

    class Meta:
        model = Player
        fields = ('id', 'first_name', 'last_name', 'position', 'player_detail')

create中的views.py方法如下所示:

   def create(self, request):
        serializer = PlayerSerializer(data=request.data, many=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        return Response('Player cannot be created', status=status.HTTP_400_BAD_REQUEST)

好吧,我向这个简单的API发送了一个JSON请求。我发送的对象是:

 {
        "first_name": "Player1",
        "last_name": "Player1",
        "position": "DEFENDER",
        "player_detail": {
             "weight": 80,
              "height": 180
        }
}

结果我只看到400个错误请求和Player cannot be created。我不知道为什么这是错的。我认为我的关系很好。 通过JSON创建连接对象的好方法是什么?

修改 现在我的序列化器看起来像:

class PlayerDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = PlayerDetail
        fields = ('weight', 'height')


class PlayerSerializer(serializers.ModelSerializer):
    player_detail = PlayerDetailSerializer(many=True)

    class Meta:
        model = Player
        fields = ('id', 'first_name', 'last_name', 'position', 'player_detail')

    def create(self, validated_data):
        player_detail = validated_data.pop('player_detail')
        player = Player.objects.create(**validated_data)
        PlayerDetail.objects.create(player=player, **player_detail)
        return player

但我仍然收到此错误: {'player_detail': {'non_field_errors': ['Expected a list of items but got type "dict".']}}

我也尝试在many=True中没有PlayerDetailSerializer的情况下执行此操作,然后serializer.save()被调用,但我在return self.cursor.execute(sql, params) django.db.utils.IntegrityError中得到一个空列值player_detail_id。< / p>

编辑2: 我已经解决了这个问题。我已将序列化程序中的create方法更改为:

  def create(self, validated_data):
        player_detail = PlayerDetail.objects.create(**validated_data.pop('player_detail'))
        player = Player.objects.create(player_detail=player_detail, **validated_data)
        return player

现在已经创建了嵌套reliationship对象。

1 个答案:

答案 0 :(得分:1)

我认为您的create方法位于PlayerDetailSerializer?请注意,它将验证的数据作为参数,您正在传递请求。

此外,您必须手动弹出PlayerDetail“,然后创建模型实例。因为您不这样做,所以在验证播放器时,dict位于经过验证的数据中。然后将对象键传递给Player.objects.create方法。我无法解释它比documentation更好,但我会从文档中粘贴create方法,因为我认为这是你必须改变的。

def create(self, validated_data):
    tracks_data = validated_data.pop('tracks')
    album = Album.objects.create(**validated_data)
    for track_data in tracks_data:
        Track.objects.create(album=album, **track_data)
    return album

如果我误解了你的问题,请告诉我,所以我可以编辑这个答案。