【问题标题】:DRF pass data into RelatedFieldDRF 将数据传递到相关字段
【发布时间】:2018-08-03 15:59:07
【问题描述】:

我有一个序列化器和一个用于通用外键关系的相关字段 这应该用于序列化 content_object 这是一个 ContentType 实例。我需要检查我在相关字段中序列化的Notification 对象的type,以正确知道哪些附加字段要序列化到其中的data 参数中。实现这一目标的最佳方法是什么?

class NotificationRelatedField(serializers.RelatedField):

    def to_representation(self, value):
        data = {}
        # Need to check notification 'type' here
        return data


class NotificationRetrieveSerializer(serializers.ModelSerializer):
    content_object = NotificationRelatedField(read_only=True)

    class Meta:
        model = Notification
        fields = [
            'id',
            'created_at',
            'is_read',
            'type',
            'content_object',
        ]

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    您可以使用SerializerMethodField 作为序列化通用 FK 关系,

    class Content_Model_1_serializer(serializers.ModelSerializer):
        # you code
    class Content_Model_2_serializer(serializers.ModelSerializer):
        # your code
    
    class NotificationRetrieveSerializer(serializers.ModelSerializer):
        content_object = serializers.SerializerMethodField(read_only=True)
    
        def get_content_object(self, notification):
            if isinstance(notification.content_object, Content_Model_1):
                return Content_Model_1_serializer(notification.content_object).data
            if isinstance(notification.content_object, Content_Model_2):
                return Content_Model_2_serializer(notification.content_object).data
            ## and so on
            return None  # default case
    
        class Meta:
            model = Notification
            fields = [
                'id',
                'created_at',
                'is_read',
                'type',
                'content_object',
            ]

    Content_Model_1Content_Model_2 是通过通用 FK 关系关联的模型,Content_Model_1_serializerContent_Model_2_serializer 是三个序列化器。

    【讨论】:

      【解决方案2】:

      您需要重写序列化程序的to_representation 方法,以使用Notification 实例而不是字段的值来调用字段的to_representation 方法。

      示例

      class NotificationRetrieveSerializer(serializers.ModelSerializer):
          content_object = NotificationRelatedField(read_only=True)
      
          class Meta:
              model = Notification
              fields = [
                  'id',
                  'created_at',
                  'is_read',
                  'type',
                  'content_object',
              ]
      
          # override to_representation method
          def to_representation(self, instance):
              # python3 for `super` call
              result = super().to_representation(instance)
      
              # python2 for `super` call
              # result = super(
              #     NotificationRetrieveSerializer, self
              # ).to_representatio(instance)
      
              # here you call your field's `to_representation` with current instance
              # as the argument rather than as the `value` of the field.
              result['content_object'] = content_object_field.to_representation(instance)
      
              return result
      
      class NotificationRelatedField(serializers.RelatedField):
      
          # here `value` is now the `Notification` instance
          def to_representation(self, value):
              data = {}
      
              # get the type and this field's value
              type = value.type
              content_object = value.content_object
      
              return data
      

      【讨论】:

        猜你喜欢
        • 2023-03-13
        • 1970-01-01
        • 2013-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多