代码之家  ›  专栏  ›  技术社区  ›  saran3h

Django序列化程序:如何验证模型实例?

  •  0
  • saran3h  · 技术社区  · 7 年前

    我有一个相当一般的场景,在这个场景中我调用api,它只是在我的模型对象中设置一个字段并保存它(假设记录已经存在并且正在更新)。但是,我需要在保存之前验证这个模型对象。

    api.py公司

    @detail_route(methods=['POST'], url_path='submit-draft')
    def submit_draft(self, request, *args, **kwargs):
        booking = self.get_object()
    
        # serializer with custom validations.
        serializer = self.get_serializer(booking)
        serializer.is_valid(raise_exception=True)
    
        booking.submit_draft(by=request.user)
        booking.save()
    
        data = serializers.BookingDetailSerializer(booking, context={'request': request}).data
    
        return response.Ok(data)
    

    序列化程序.py

    class BookingCreateUpdateSerializer(serializers.ModelSerializer):
        date = serializers.CharField()
    
        duration = serializers.IntegerField(required=True, )
    
        created_by = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault(), )
    
        modified_by = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault(), )
        ....
    
        class Meta:
        model = models.Booking
            fields = [
            'title',
            'date',
            'duration',
            'client',
            'created_by',
            'modified_by',
            ....
        ]
    

    但是,我得到一个错误:

    AssertionError: Cannot call '.is_valid()' as no 'data=' keyword argument was passed when instantiating the serializer instance.

    2 回复  |  直到 6 年前
        1
  •  5
  •   Enthusiast Martin    7 年前

    可以使用序列化程序:

    1) 将对象序列化为字典。在这种情况下,您不需要调用is\u valid,因为对象已经创建,并且它具有有效值。因此,您可以执行以下操作:

    serializer = BookingCreateUpdateSerializer(booking)
    
    return Response(serializer.data)
    

    serializer = BookingCreateUpdateSerializer(data=input_dict)
    serializer.is_valid()
    serializer.save()
    

    可以执行以下操作以使用序列化程序更新实例:

    serializer = BookingCreateUpdateSerializer(booking, data=input_data_to_update, partial=True)
    serializer.is_valid()
    
    instance = serializer.save()
    
    # and serialize the updated instance for response using another serializer
    output_data = BookingDetailSerializer(instance).data
    
        2
  •  0
  •   saran3h    6 年前

    在花了将近一天的时间挠头之后,这终于奏效了。

    api.py公司

    @detail_route(methods=['POST'], url_path='submit-draft')
    def submit_draft(self, request, *args, **kwargs):
        # Step1. Get current model instance.
        booking = self.get_object()
    
        # Step2. Serialize the model instance using same serializer as in Step5.
        booking_data = serializers.BookingDetailSerializer(booking, context={'request': 
        request}).data
    
        # Step3. Deserialize the data from Step2 (using `BookingCreateUpdateSerializer` serializer 
        as mentioned in description and check for validations.
        serializer = self.get_serializer(data=booking_data)
        serializer.is_valid(raise_exception=True)       
    
        # Step4. If no validation error, set the required field and save the instance.
        booking.submit_draft(by=request.user)
        booking.save()
    
        # Step5. Return response.
        data = serializers.BookingDetailSerializer(booking, context={'request': request}).data
    
        return response.Ok(data)
    

    今天我学到了更多关于连载器的知识。我们可以将模型实例传递到不同的序列化程序中,并根据需要更改其形状。