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.

DRF: Obtener campos de serializador anidados para verificaciones personalizadas

Mis Clases de Modelo

class Master(models.Model):
    date_signed= models.DateField()
    info1 = models.CharField(max_length=255)
    info2 = models.CharField(max_length=255)

class Detail(models.Model):
    date_start = models.DateField()
    date_end = models.DateField()
    info3 = models.CharField(max_length=255)
    info4 = models.CharField(max_length=255)
    master = models.OneToOneField(Master,on_delete=models.CASCADE,related_name='detail')

Aquí están mis serializadores de master y detail.

class MasterSerializer(serializers.ModelSerializer):

    class Meta:
        model = Master
        fields = ['id', 'date_signed', 'info1', 'info2']

class DetailSerializer(serializers.ModelSerializer):
    master = MasterSerializer(read_only=True)

    class Meta:
        model = Detail
        fields = ['id', 'master', 'date_start', 'date_end', 'info3', 'info4', ...]

    def validate(self, attrs):
        # 1. verificar si la fecha de firma es siempre anterior a la fecha de inicio
        # 2. verificar si la fecha de inicio es mayor que la fecha de finalización

Lo que estoy tratando de hacer es comprobar si la fecha firmada en el serializador de Master siempre es una fecha anterior a la de inicio. Para eso, necesito la date_signed en el serializador de Detail. ¿Cómo puedo obtenerla? Puede que sea una pregunta más sencilla, pero me resulta difícil ya que acabo de empezar a aprender drf. He buscado mucho, pero no he encontrado la solución que necesitaba.

Espero obtener ayuda para orientarme en la dirección correcta.

Gracias de antemano.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para acceder al campo date_signed del serializador Master dentro del serializador Detail con fines de validación, puedes crear un campo personalizado en el serializador Detail y anular el método to_representation para extraer el campo deseado de la instancia relacionada Master. Aquí tienes un ejemplo de fragmento de código:

    class MasterDateSerializer(serializers.Field):
        def to_representation(self, instance):
            master_date = instance.master.date_signed
            return master_date
    
    class DetailSerializer(serializers.ModelSerializer):
        master_date = MasterDateSerializer(source='*')
    
        class Meta:
            model = Detail
            fields = ['id', 'master', 'master_date', 'date_start', 'date_end', 'info3', 'info4']
    
        def validate(self, attrs):
            # 1. Verificar si la fecha de firma siempre es mayor que la fecha de inicio
            master_date = attrs['master'].master_date
            date_start = attrs['date_start']
            if master_date >= date_start:
                raise serializers.ValidationError("date_signed debe ser anterior a date_start.")
    
            # 2. Verificar si la fecha de inicio es mayor que fecha de fin
            date_end = attrs['date_end']
            if date_start >= date_end:
                raise serializers.ValidationError("date_start debe ser anterior a date_end.")
    
            return attrs
    

    En este código, definimos un campo de serializador personalizado llamado MasterDateSerializer que extrae el valor date_signed de la instancia Master usando el argumento source establecido en '*'. Luego podemos incluir este campo en el serializador Detail como master_date.

    Dentro del método validate del serializador DetailSerializer, ahora podemos acceder al valor master_date a través de attrs['master'].master_date y realizar las validaciones deseadas. Si el valor date_signed no es anterior a date_start, lanzamos un error de validación. De manera similar, si date_start no es anterior a date_end, lanzamos otro error de validación.

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

Comments are closed.