我为相关模型创建了一个代码:
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对象。
答案 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
如果我误解了你的问题,请告诉我,所以我可以编辑这个答案。