Skip to content
thesarfo

Note

Saving Objects with a Serializer

Using serializer.save() to create/update, and overriding create() and update() for custom logic.

views 0

Note that our serializer class inherits from a modelserializer class, now this modelserializer class has a method called save that we can use to creating/updating objects into the database. see below

@api_view(['GET', 'POST'])
def product_list(request):
if request.method == 'GET':
queryset = Product.objects.select_related('collection').all()
serializer = ProductSerializer(queryset, many=True, context={'request': request})
return Response(serializer.data)
elif request.method == 'POST':
serializer = ProductSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
'''save it right after validation'''
serializer.save()
return Response('ok')

Notice how we dont need the ‘serializer.validated_data’ because ‘serializer.save()’ has some in built logic that extracts data from the dictionary to create or update an object(product).

What if you wanna override how a product is created, like you wanna set some special fields or associate the product with another object in the database. In your serializer class, you can override the create method. The method takes the self and validated_data dictionary. So here you can create an instance of the Product class, and unpack the validated_data dictionary. Then you can set those special fields, then save the product…and then return the product. See below..

class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ['id', 'title', 'description', 'slug', 'inventory', 'unit_price', 'price_with_tax', 'collection']
price_with_tax = serializers.SerializerMethodField(method_name='calculate_tax')
def calculate_tax(self, product: Product):
return product.unit_price * Decimal(1.1)
def create(self, validated_data):
product = Product(**validated_data)
product.other = 1
product.save()
return product

Just like how you can override the save method, you can override the update method as well. With this one you can create a method called update which takes self, instance and validated_data as parameters. Where the instance is the product object. So you update the field of the instance you want to update, with what you want to update it with..and then you save the instance and return the instance. see below

class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ['id', 'title', 'description', 'slug', 'inventory', 'unit_price', 'price_with_tax', 'collection']
price_with_tax = serializers.SerializerMethodField(method_name='calculate_tax')
def calculate_tax(self, product: Product):
return product.unit_price * Decimal(1.1)
def create(self, validated_data):
product = Product(**validated_data)
product.other = 1
product.save()
return product
def update(self, instance, validated_data):
''' we then set the field we want to update, and then save it'''
instance.unit_price = validated_data.get('unit_price')
instance.save()
return instance