es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Django Rest Framework: Después de agregar un campo relacionado con un serializador, obtengo un error de integridad.

Tenía el siguiente serializador. Django Rest Framework me permite crear, actualizar, eliminar y obtener información solo con este código. Por supuesto, estoy agregando el serializador al viewset, pero el problema no está ahí:

class MeasurmentSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Measurment
        fields = ('id', 'user_statistic', 'value', 'date_created')

Necesitaba agregar la información detallada para el campo “user_statistic” cada vez que obtengo los datos, no solo la URL, así que agregué el código en la segunda línea y funcionó, obtuve la información adicional que necesitaba:

class MeasurmentSerializer(serializers.HyperlinkedModelSerializer):
    user_statistic = UserStatisticSerializer(read_only=True) # Nuevo código agregado

    class Meta:
        model = Measurment
        fields = ('id', 'user_statistic', 'value', 'date_created')

Sin embargo, cuando envío una solicitud POST a la API para crear nueva información en la base de datos, muestra el siguiente error:

> NotNullViolation: valor nulo en la columna "statistic_id" de la relación "cms_userstatistic" viola la restricción de no nulo DETAIL: La fila fallada contiene (55, 6, 0, f, f, null, 2022-01-05, 2022-01-05, null, 67).

Parece que serializar un campo relacionado evita que DRF obtenga la información del campo relacionado cuando intenta crear un nuevo objeto. ¿Cómo puedo agregar la información detallada para ese campo relacionado específico sin romper la solicitud POST? Me pregunto si hay otra manera de obtener esta información sin usar la función “to_representation” que me permite personalizar el objeto resultante.

Agradezco cualquier pista que me puedan dar.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema ocurre porque el serializador está serializando el campo relacionado como de solo lectura, lo que significa que cuando se está creando un nuevo objeto, DRF no puede obtener la información del campo relacionado debido a esta restricción.

    Para resolver este problema, puedes quitar el parámetro “read_only=True” del serializador UserStatisticSerializer y agregar el parámetro “required=False” al campo user_statistic en el serializador MeasurmentSerializer, de esta manera:

    class MeasurmentSerializer(serializers.HyperlinkedModelSerializer):
        user_statistic = UserStatisticSerializer(required=False)
    
        class Meta:
            model = Measurment
            fields = ('id', 'user_statistic', 'value', 'date_created')
    
        def create(self, validated_data):
            user_statistic_data = validated_data.pop('user_statistic')
            user_statistic = UserStatistic.objects.get(**user_statistic_data)
            return Measurment.objects.create(user_statistic=user_statistic, **validated_data)
    

    Con esta implementación, cuando se esté creando un nuevo objeto, el campo user_statistic no será requerido, pero si lo proporcionas, DRF lo utilizará para crear el objeto UserStatistic correspondiente y vincularlo al nuevo objeto Measurment.

    ¡Espero que esto ayude! Déjame saber si tienes alguna otra pregunta.

Comments are closed.