Validación única en el serializador nested en Django Rest Framework

Tengo un caso como este, donde tiene una relación de serializador nested personalizado con un campo único. Caso de la muestra:

class GenreSerializer(serializers.ModelSerializer): class Meta: fields = ('name',) #This field is unique model = Genre class BookSerializer(serializers.ModelSerializer): genre = GenreSerializer() class Meta: model = Book fields = ('name', 'genre') def create(self, validated_data): genre = validated_data.pop('genre') genre = Genre.objects.get(**genre) return Book.objects.create(genre=genre, **validated_data) 

El problema: cuando bash guardar un objeto json como {“nombre”: “El Príncipe”, “género”: {“nombre”: “Historial”}} DRF intente validar la restricción única del objeto de género y si “Historial” existe una excepción, porque un género con nombre “Historial” debe ser único, y eso es cierto, pero solo trato de relacionar el objeto y no crearlo juntos.

¡¡Muchas gracias!!

Debería descartar el validador único para el serializador nested:

 class GenreSerializer(serializers.ModelSerializer): class Meta: fields = ('name',) #This field is unique model = Genre extra_kwargs = { 'name': {'validators': []}, } 

Es posible que desee imprimir su serializador antes para asegurarse de que no tiene otros validadores en ese campo. Si tienes alguno, deberás incluirlos en la lista.

Edición: si necesita garantizar la restricción de unicidad para la creación, debe hacerlo en la vista después de que se haya llamado al serializer.save y antes del serializer.save .

Esto sucede porque el serializador nested ( GenreSerializer ) necesita una instancia del objeto para validar la restricción única correctamente (como poner una cláusula de exclude en el queryset utilizado en la validación) y, de forma predeterminada, un serializador no pasará la instancia de los objetos relacionados a archivos archivados Son serializadores nesteds cuando se ejecuta el método to_internal_value() . Ver aqui

Otra forma de resolver este problema es anular el método get_fields() en el serializador principal y pasar la instancia del objeto relacionado

 class BookSerializer(serializers.ModelSerializer): def get_fields(self): fields = super(BookSerializer, self).get_fields() try: # Handle DoesNotExist exceptions (you may need it) if self.instance and self.instance.genre: fields['genre'].instance = self.instance.genre except Genre.DoesNotExist: pass return fields