I've a ModelSerializer class
which uses an IntegerField
as a replace for a ForeingKey
relation.
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
I've two questions about this class, first regarding the code, the validate_product_id
method does a db call to check if the requested Product object exists and then inside the save
method there is another call to db to get the same Product again, I think this way is not optimized for querying the same object twice. Is there a better way to check for the existence or raising proper error?
second if I use get_object_or_404
the amount of code to write will decrease but there is no chance to raise a concise but relevant Error Message, so What do you usually do?
CodePudding user response:
Usually one would use a special field type PrimaryKeyRelatedField
.
You don't even need to manually declare one, as it can be done automatically by the 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