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

Django RESTAPI:序列化模型时如何去掉json中的“UUID”?

  •  9
  • meowmeow  · 技术社区  · 8 年前

    为什么“UUID”出现在“profile”键的值之前,如何正确删除它?

    花名册/序列化程序。py公司

    class ShiftSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Shift
        fields = ('id', 'profile', 'location', 'date', 'start_time', 'end_time')
    

    class Profile(models.Models):
        id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
    

        id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
        profile = models.ForeignKey('profiles.Profile', null=True, blank=True)
    

    python管理。py外壳

    from roster.models import Shift
    from roster.serializers import ShiftSerializer
    
    myshift = Shift.objects.first()
    serializer = ShiftSerializer(myshift)
    serializer.data
    

    输出:

    {'id': '92ca258e-8624-434a-b61d-e1cd3b80e0e8', 'profile': UUID('0081b028-0a11-47fb-971e-c47177ed93be')
    
    4 回复  |  直到 8 年前
        1
  •  14
  •   illagrenan Luper Rouch    7 年前

    tl;博士

    看见 在底部。

    问题

    .data 序列化程序应仅返回对象的基元表示( http://www.django-rest-framework.org/api-guide/serializers/#baseserializer to_representation() 方法( http://www.django-rest-framework.org/api-guide/serializers/#to_representationself-obj

    @six.add_metaclass(SerializerMetaclass)
    class Serializer(BaseSerializer):
    
        # ...
        # ...
    
        def to_representation(self, instance):
            """
            Object instance -> Dict of primitive datatypes.
            """
            # ...
            # ...
    
            for field in fields:
    
                # ...
                # ...
    
                if check_for_none is None:
                    ret[field.field_name] = None
                else:
                    ret[field.field_name] = field.to_representation(attribute)
    
            return ret
    

    资料来源: https://github.com/encode/django-rest-framework/blob/master/rest_framework/serializers.py#L505-L529

    模型有一个问题 uuid.UUID 作为主键。 PrimaryKeyRelatedField uuid。UUID UUID('')

    什么时候 pk_field 属性打开 to_representation 方法仅返回

    class PrimaryKeyRelatedField(RelatedField):
        # ...
    
        def to_representation(self, value):
            if self.pk_field is not None:
                return self.pk_field.to_representation(value.pk)
            return value.pk
    

    https://github.com/encode/django-rest-framework/blob/master/rest_framework/relations.py#L269-L272

    为什么这是个问题

    如其他答复和评论所述, JSONRenderer http://www.django-rest-framework.org/api-guide/serializers/#serializing-objects )

    from rest_framework.renderers import JSONRenderer
    
    json_data = JSONRenderer().render(serializer.data)
    

    但有些情况下,你不想使用 JSONRenderer

    • 你在比较 .数据
    • 你需要存储 .数据 在数据库、文件中。。。
    • .数据 通过 requests 对于某些API: requests.post(..., json=serializer.data)
    • ...

    设置 pk_字段 属性打开 UUIDField() :

    from rest_framework import serializers
    from rest_framework.fields import UUIDField
    
    
    class ExampleSerializer(serializers.ModelSerializer):
        id = serializers.PrimaryKeyRelatedField(required=True,
                                                allow_null=False,
                                                # This will properly serialize uuid.UUID to str:
                                                pk_field=UUIDField(format='hex_verbose'))
    

    uuid。UUID 实例将正确序列化为 str serializer.data .

        2
  •  1
  •   study-machine    8 年前

    你可以重写 representation

    class ShiftSerializer(serializers.ModelSerializer):
        class Meta:
            model = Shift
            fields = '__all__'
    
        def to_representation(self, obj):
            return {
                "id": obj.id,
                "profile": obj.profile.id,
                "location": obj.location,
                "date": obj.date,
                "start_time": obj.start_time,
            }
    
        3
  •  0
  •   Brown Bear    8 年前

    您可以尝试使用序列化程序。查菲尔德

    class ShiftSerializer(serializers.ModelSerializer):
         profile = serializers.CharField(read_only=True)
    
        4
  •  0
  •   meowmeow    8 年前