#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. Спасибо. Использовали первый метод. В соответствии с вашим опытом,какой из них более эффективен.