DRF : Получение вложенных полей сериализатора для пользовательских проверок

#python #django #django-rest-framework #django-serializer

#питон #джанго #django-rest-фреймворк #джанго-сериализатор

Вопрос:

Мои Классы Моделей

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

Вот мой мастер и сериализаторы деталей.

 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  

Что я пытаюсь сделать, так это проверить, всегда ли date_signed в главном сериализаторе является датой перед датой начала. Для этого мне нужна дата, подписанная в сериализаторе подробностей. Так как же я могу его получить? Может быть, это более простой вопрос, но мне это трудно, так как я только начал изучать drf. Я много искал, но не мог найти нужное мне решение.

Надеюсь получить помощь, которая укажет мне правильное направление.

Заранее спасибо

Комментарии:

1. Можете ли вы поделиться своим кодом просмотра? и какова взаимосвязь между Основной и детальной моделью?

2. @RohanBaddi включил модели в код

3. Если тип поля мастера доступен только для чтения, то как вы назначаете экземпляр мастера главному полю детали? Существует ли какая-либо другая конечная точка для создания Мастеров?

4. @RohanBaddi через контекст я передаю master_id и использую его в методе создания

Ответ №1:

Если вы хотите использовать контекст для 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 gt; attrs.get("date_start"):  raise ValidationError(detail="Error Message!")  # 2. check date start is greater than date end  if attrs.get("date_start") gt; attrs.get("date_end"):  raise ValidationError(detail="Error Message!")  return attrs  

Вместо использования контекста для master_id в этом мы используем полезную нагрузку. Если мы хотим изменить представление нашего сериализатора, нам нужно переопределить эту функцию to_representation.

 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 gt; attrs.get("date_start"):  raise ValidationError(detail="Error Message!")  # 2. check date start is greater than date end  if attrs.get("date_start") gt; attrs.get("date_end"):  raise ValidationError(detail="Error Message!")  return attrs  

Комментарии:

1. Спасибо. Использовали первый метод. В соответствии с вашим опытом,какой из них более эффективен.