Reputation: 1249
I have a writable nested serializer like this -
class AddressSerializer(serializers.ModelSerializer):
class Meta:
model = publicAddress
fields = "__all__"
class customerSerializer(serializers.ModelSerializer):
publicAdd = AddressSerializer(many=True)
class Meta:
model = customerMaster
fields = ['id','publicAdd']
def create(self, validated_data):
Address = validated_data.pop('publicAdd')
customer = customerMaster.objects.create(**validated_data)
for addres in Address:
publicAddress.objects.create(customer=customer, **addres)
return customer
this all works fine until I apply validation such as
class AddressSerializer(serializers.ModelSerializer):
class Meta:
model = publicAddress
fields = "__all__"
validators = [
UniqueTogetherValidator(
queryset=publicAddress.objects.all(),
fields=['customer', 'someValue']
)
]
And defining
read_only_fields = ('customer',)
in AddressSerializer won't help either.
Now it throws an error such as cust field is always required and to send the cust value via api.
Any help on how to validate this without an error?
Upvotes: 0
Views: 564
Reputation: 2380
customer
is a read-only field. it means DRF
only uses it for responses after creating your object. but in UniqueTogetherValidator
it needs data before creating it.
As DRF
says in documentation:
The
UniqueTogetherValidator
class always imposes an implicit constraint that all the fields it applies to are always treated as required. Fields with default values are an exception to this as they always supply a value even when omitted from user input.
So you need to handle it manually:
class customerSerializer(serializers.ModelSerializer):
publicAdd = AddressSerializer(many=True)
class Meta:
model = customerMaster
fields = ['id','publicAdd']
def create(self, validated_data):
Address = validated_data.pop('publicAdd')
customer = customerMaster.objects.create(**validated_data)
for addres in Address:
publicAddress.objects.create(customer=customer, **addres)
return customer
def validate(self, attrs):
# customer is not in attrs because it's read-only
# Maybe you need to add context data to your serializer or get it somehow you know
object_exists = publicAddress.objects.filter(
customer=your_customer, someValue=attrs["someValue"]
).exists()
if object_exists:
raise serializer.ValidationError("Duplicate object")
return attrs
Upvotes: 2