meo*_*eow 4 django django-serializer django-rest-framework
为什么“ UUID”出现在“配置文件”键值的前面,如何正确删除?
名册/serializers.py
class ShiftSerializer(serializers.ModelSerializer):
class Meta:
model = Shift
fields = ('id', 'profile', 'location', 'date', 'start_time', 'end_time')
Run Code Online (Sandbox Code Playgroud)
个人资料/models.py
class Profile(models.Models):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
Run Code Online (Sandbox Code Playgroud)
名册/models.py
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
profile = models.ForeignKey('profiles.Profile', null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)
python manage.py shell
from roster.models import Shift
from roster.serializers import ShiftSerializer
myshift = Shift.objects.first()
serializer = ShiftSerializer(myshift)
serializer.data
Run Code Online (Sandbox Code Playgroud)
输出:
{'id': '92ca258e-8624-434a-b61d-e1cd3b80e0e8', 'profile': UUID('0081b028-0a11-47fb-971e-c47177ed93be')
Run Code Online (Sandbox Code Playgroud)
tl; dr
请参阅底部的解决方案。
问题
.dataSerializer上的属性应仅返回对象的原始表示形式(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
Run Code Online (Sandbox Code Playgroud)
来源:https : //github.com/encode/django-rest-framework/blob/master/rest_framework/serializers.py#L505-L529
具有uuid.UUID作为主键的模型存在问题。PrimaryKeyRelatedField返回uuid.UUID实例-这显然不是原始类型,导致例如UUID('')不是JSON可序列化错误。
如果未设置pk_fieldon属性,PrimaryKeyRelatedField则to_representation方法仅返回uuid.UUID实例,请参见相关代码:
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
Run Code Online (Sandbox Code Playgroud)
来源: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)
Run Code Online (Sandbox Code Playgroud)
但是在某些情况下,您不想使用JSONRenderer:
.data在单元测试期间进行比较;.data在数据库中,文件,....data通过发送requests到一些API:requests.post(..., json=serializer.data)解决方案
将pk_field属性设置PrimaryKeyRelatedField为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'))
Run Code Online (Sandbox Code Playgroud)
并且uuid.UUID实例将str在访问时正确序列化到serializer.data。
小智 1
你可以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,
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1748 次 |
| 最近记录: |