【问题标题】:Django REST Framework create nested serializers gives pk errorDjango REST Framework 创建嵌套序列化程序给出 pk 错误
【发布时间】:2019-01-29 03:30:09
【问题描述】:

我的模型:

class ContentHotel(models.Model):
    hotel_id = models.IntegerField(unique=True, blank=True, primary_key=True)

    class Meta:
        managed = False
        db_table = 'content_hotels'
        ordering = ('hotel_id',)

    def __str__(self):
        return str(self.hotel_id)


class RateHotel(models.Model):
    rate_hotel_id = models.IntegerField(blank=True, primary_key=True, unique=True)
    content_hotel = models.ForeignKey(ContentHotel, on_delete=models.CASCADE, related_name='rate_hotel')

    class Meta:
        managed = False
        db_table = 'rate_hotels'
        ordering = ('rate_hotel_id',)

    def __str__(self):
        return str(self.rate_hotel_id)

我的序列化器:

class RateHotelSerializer(serializers.ModelSerializer):

    class Meta:
        model = RateHotel
        fields = __all__


class ContentHotelSerializer(serializers.ModelSerializer):
    rate_hotel = RateHotelSerializer(many=True)

    class Meta:
        model = ContentHotel
        fields = ('hotel_id', 'rate_hotel')

    def create(self, validated_data):
        rate_hotels = validated_data.pop('rate_hotel')
        content_hotel = ContentHotel.objects.create(**validated_data)

        for rate_hotel in rate_hotels:
            RateHotel.objects.create(content_hotel=content_hotel, **rate_hotel)

        return content_hotel

JSON:

{
    "hotel_id": -1,
    "rate_hotel": [{"content_hotel": -1, "rate_hotel_id": 1}]
}

上面的 JSON 输入给了我这样的错误:

{
    "rate_hotel": [
        {
            "content_hotel": [
                "Invalid pk \"1\" - object does not exist."
            ]
        }
    ],
    "status_code": 400
}

参考:http://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers

我参考了上面的链接,有人知道如何解决这个问题吗?但是如果我分别创建这两个对象,它可以正常工作,如下所示:

{
    "hotel_id": -1,
}

{
    "content_hotel": -1, 
    "rate_hotel_id": 1
}

【问题讨论】:

  • 你能在这两种情况下检查 .create() 中的 rate_hotels 的值是多少吗?
  • 我认为你的错误在于传递 "rate_hotel_id": 1 在第一种情况下,你不应该传递要创建的 id 的对象。
  • 它与“rate_hotel_id”无关,它是一个验证错误,就像@changak提到的一样。

标签: django django-rest-framework


【解决方案1】:

验证已在序列化程序create 函数之前完成,并且由于您尚未使用该 pk 创建 contenthotel,因此该字段 (content_hotel) 的 pk 无效。在 RateHotelSerializer 中将 content_hotel 设为只读,问题将得到解决,将序列化程序更改为:

class RateHotelSerializer(serializers.ModelSerializer):

    class Meta:
        model = RateHotel
        fields = __all__
        read_only_fields = ('content_hotel', )

而且现在您不需要在rate_hotel 的列表对象中添加content_hotel,使用这样的json:

{
    "hotel_id": -1,
    "rate_hotel": [{"rate_hotel_id": 1}]
}

【讨论】:

  • 非常感谢,现在我可以成功创建嵌套对象,但是我不能再创建rate_hotel对象了,有没有办法解决这个问题?提前致谢。
  • 我不知道为什么您首先要从用户那里获取(模型的)pk用于创建,它应该在模型中自动生成。无论如何,如果您想保持这种方法,最好的方法是使用新的序列化程序(就像我编辑之前的旧序列化程序)只创建一个 rate_hotel。
  • 非常感谢,问题已解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 2018-07-14
  • 2015-11-09
  • 2018-05-20
  • 1970-01-01
  • 1970-01-01
  • 2016-02-09
相关资源
最近更新 更多