Ошибка валидации на вложенном сериализаторе с возможностью записи
У меня есть записываемый вложенный сериализатор, такой как этот -
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
все это работает нормально, пока я не применю валидацию, например,
class AddressSerializer(serializers.ModelSerializer):
class Meta:
model = publicAddress
fields = "__all__"
validators = [
UniqueTogetherValidator(
queryset=publicAddress.objects.all(),
fields=['customer', 'someValue']
)
]
И определение
read_only_fields = ('customer',)
в AddressSerializer тоже не поможет.
Теперь он выдает ошибку типа cust поле всегда обязательно и для отправки значения cust через api.
Помогите, как проверить это без ошибки?
customer
- это поле только для чтения. это означает, что DRF
использует его только для ответов после создания вашего объекта. но в UniqueTogetherValidator
ему нужны данные перед созданием.
Как сказано в документации DRF
:
Класс
UniqueTogetherValidator
всегда накладывает неявное ограничение на то, что все поля, к которым он применяется, всегда рассматриваются как обязательные. Поля со значениями default являются исключением, так как они всегда предоставляют значение, даже если оно опущено при вводе пользователем.
Поэтому вам нужно обработать его вручную:
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