简体   繁体   中英

DRF : Getting nestted serializer fields for custom checks

My Model Classes

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')

Here is my master and detail serializers.

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. check if date sign is always grater than date start
         # 2. check date start is greater than date end

What i am trying to do is to check if the date_signed in master serializer is always a date before the date_start one. For that i need the date_signed in the detail serializer. So how can i get it. May be is a simpler question, but i am finding it difficult as i just started learning drf. I searched a lot, but couldnt get the solution i needed.

Hope to get some help to point me in the right direction.

Thanks in advance

If you want to use context for master_id.

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. check if date sign is always grater than date start
         if Master.objects.get(id=self.context.get("master_id")).date_signed > attrs.get("date_start"):
             raise ValidationError(detail="Error Message!")
         # 2. check date start is greater than date end
         if attrs.get("date_start") > attrs.get("date_end"):
             raise ValidationError(detail="Error Message!")
         return attrs

Instead of using context for master_id in this we are using payload. If we want to change to representation of our serializer then we need to override this to_representation function.

class MasterSerializer(serializers.ModelSerializer):
  
     class Meta:
         model = Master
         fields = ['id','date_signed','info1','info2']

class DetailSerializer(serializers.ModelSerializer):
     master = serializers.PrimaryKeyRelatedField(queryset=Master.objects.all())

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

     def to_representation(self, obj):
         data = super().to_representation(obj)
         data.update({"master": MasterSerializer(obj.master).data})
         return data

     def validate(self, attrs):
         # 1. check if date sign is always grater than date start
         if attrs.get("master").date_signed > attrs.get("date_start"):
             raise ValidationError(detail="Error Message!")
         # 2. check date start is greater than date end
         if attrs.get("date_start") > attrs.get("date_end"):
             raise ValidationError(detail="Error Message!")
         return attrs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM