DRF 序列化程序 IntegerField 验证以确保 ForeignKey 确实存在

DRF Serializer IntegerField Validation To Make Sure ForeignKey Does Exists

我有一个 ModelSerializer class,它使用 IntegerField 作为 ForeingKey 关系的替换。

class CartItemCreateSerializer(serializers.ModelSerializer):
    product_id = serializers.IntegerField()

    class Meta:
        model = CartItem
        fields = ('id', 'product_id', 'quantity')

    def validate_product_id(self, value):
        if not Product.objects.filter(pk=value).exists():
            raise serializers.ValidationError('Product not found')
        return value

    def save(self, **kwargs):
        product_id = self.validated_data['product_id']
        cart_id = self.context['cart_id']
        product = Product.objects.get(id=product_id)
        # product = get_object_or_404(Product, id=product_id)
        cart_item, _ = CartItem.objects.get_or_create(
            cart_id=cart_id, product=product)
        cart_item.quantity += self.validated_data['quantity']
        cart_item.save()
        self.instance = cart_item
        return self.instance

关于这个 class 我有两个问题,首先是关于代码,validate_product_id 方法执行数据库调用以检查请求的 Product 对象是否存在,然后在 save 方法有另一个调用 db 再次获得相同的产品,我认为这种方式没有针对两次查询同一对象进行优化。有没有更好的方法来检查是否存在或引发适当的错误? 第二,如果我使用 get_object_or_404 代码量会减少,但没有机会提出简洁但相关的错误消息,所以你通常做什么?

通常人们会使用一种特殊的字段类型PrimaryKeyRelatedField。 您甚至不需要手动声明一个,因为它可以由 ModelSerializer.

自动完成
class CartItemCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = CartItem
        fields = ('id', 'product', 'quantity')

    def save(self, **kwargs):
        cart_id = self.context['cart_id']
        product = self.validated_data['product']
        cart_item, _ = CartItem.objects.get_or_create(
            cart_id=cart_id, product=product)
        cart_item.quantity += self.validated_data['quantity']
        cart_item.save()
        self.instance = cart_item
        return self.instance

https://www.django-rest-framework.org/api-guide/relations/#primarykeyrelatedfield