最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】Django中数据serialize后不是字典对象而是OrderedDict的list

Django crifan 3361浏览 0评论

在:

【已解决】Django中返回合并后的当前用户信息为JSON的字典对象

期间,参考之前的代码:

<code>        current_user_function_group = FunctionGroup.objects.filter(members=curUser)
        function_group_serializer = FunctionGroupSerializer(current_user_function_group, many=True)
        function_group_serializer_data = function_group_serializer.data
        logger.info("function_group_serializer_data=%s", function_group_serializer_data)

        return Response(
            {
                'current_user': curUserDict,
                # 'current_user_function_group': function_group_serializer_data,
                'current_user_function_group_list': function_group_serializer_data,
                'function_group': user_function_group_names,
                'function_group_ids': user_function_group_ids,
                'function_group_owner': user_function_group_owner,
                'function_group_functions': user_function_group_functions,
            },
            status=status.HTTP_200_OK)
</code>

去用:

<code>
        curUser = request.user
        logger.info("current_user: curUser=%s", curUser)

        userSerializer = UserSerializer(curUser, many=False)
        logger.info("userSerializer=%s", userSerializer)
        curUserDict = userSerializer.data
        logger.info("curUserDict=%s", curUserDict)

        allFunctionGroupList = FunctionGroup.objects.all()
        # function_group_names = list(allFunctionGroupList.values_list('name', flat=True))
        logger.info("allFunctionGroupList=%s", allFunctionGroupList)
        joinedFunctionGroupList = FunctionGroup.objects.filter(members=curUser)
        logger.info("joinedFunctionGroupList=%s", joinedFunctionGroupList)
        joinedFunctionGroupListSerializer = FunctionGroupSerializer(joinedFunctionGroupList, many=True)
        logger.info("joinedFunctionGroupListSerializer=%s", joinedFunctionGroupListSerializer)
        serializedJoinedFunctionGroupList = joinedFunctionGroupListSerializer.data
        logger.info("serializedJoinedFunctionGroupList=%s", serializedJoinedFunctionGroupList)

        curUserDict["joinedFunctionGroup"] = serializedJoinedFunctionGroupList
        isScriptFunctionGroupOwner = False
        ownedScriptFunctionGroup = None
        for curJoinedFunctionGroup in serializedJoinedFunctionGroupList:
            logger.info("curJoinedFunctionGroup=%s", curJoinedFunctionGroup)
            if curJoinedFunctionGroup.function == FunctionGroup.SCRIPT:
                if curJoinedFunctionGroup.owner.id == curUser.id:
                    isScriptFunctionGroupOwner = True
                    ownedScriptFunctionGroup = curJoinedFunctionGroup
                    break

</code>

结果却出错了:

<code>ERROR|20180730 15:01:35|exception:handle_uncaught_exception:118|Internal Server Error: /api/v1/users/current_user/
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/utils/deprecation.py", line 95, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 37, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 87, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 122, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/usr/local/lib/python3.6/site-packages/django_extensions/management/technical_response.py", line 6, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/Users/crifan/Library/Python/3.6/lib/python/site-packages/six.py", line 693, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/utils/deprecation.py", line 95, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 37, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 87, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 122, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/usr/local/lib/python3.6/site-packages/django_extensions/management/technical_response.py", line 6, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/Users/crifan/Library/Python/3.6/lib/python/site-packages/six.py", line 693, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/utils/deprecation.py", line 95, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 37, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 87, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 122, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/usr/local/lib/python3.6/site-packages/django_extensions/management/technical_response.py", line 6, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/Users/crifan/Library/Python/3.6/lib/python/site-packages/six.py", line 693, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/utils/deprecation.py", line 95, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 37, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 87, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 122, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/usr/local/lib/python3.6/site-packages/django_extensions/management/technical_response.py", line 6, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/Users/crifan/Library/Python/3.6/lib/python/site-packages/six.py", line 693, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/utils/deprecation.py", line 95, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 37, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 87, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 122, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/usr/local/lib/python3.6/site-packages/django_extensions/management/technical_response.py", line 6, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/Users/crifan/Library/Python/3.6/lib/python/site-packages/six.py", line 693, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/utils/deprecation.py", line 95, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 37, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 87, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 122, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/usr/local/lib/python3.6/site-packages/django_extensions/management/technical_response.py", line 6, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/Users/crifan/Library/Python/3.6/lib/python/site-packages/six.py", line 693, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/utils/deprecation.py", line 95, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 37, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 87, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 122, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/usr/local/lib/python3.6/site-packages/django_extensions/management/technical_response.py", line 6, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/Users/crifan/Library/Python/3.6/lib/python/site-packages/six.py", line 693, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/utils/deprecation.py", line 95, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 37, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 87, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 122, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/usr/local/lib/python3.6/site-packages/django_extensions/management/technical_response.py", line 6, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/Users/crifan/Library/Python/3.6/lib/python/site-packages/six.py", line 693, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/viewsets.py", line 103, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 480, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/crifan/dev/dev_root/xx/xx/projects/xx/server/xx/apps/user/views.py", line 107, in current_user
if curJoinedFunctionGroup.function == FunctionGroup.SCRIPT:
AttributeError: 'collections.OrderedDict' object has no attribute 'function'
</code>

很明显,此处的curJoinedFunctionGroup不是以为的dict。

所以报错,需要去搞清楚,如何才能把数据序列化,得到dict的json对象

而返回的数据是:

<code>[OrderedDict([('id', 5), ('owner', 'xx'), ('name', 'xx剧本组'), ('function', 'script_function_group'), ('description', 'xxx剧本组'), ('created_at', '2018-07-04 21:41:14'), ('updated_at', '2018-07-25 16:24:05')])]
</code>

而不是以为的普通的dict

去看代码:

/apps/user/serializers.py

<code>class FunctionGroupSerializer(serializers.ModelSerializer):
    owner = serializers.CharField(source='owner.username')
    function = serializers.SerializerMethodField()

    class Meta:
        model = FunctionGroup
        fields = ('id', 'owner', 'name', 'function', 'description',
                  'created_at', 'updated_at')
        read_only_fields = ('id', 'created_at', 'updated_at')

    def get_function(self, obj):
        return obj.get_function_display()
</code>

好像是自己实现的?

django serializer to dict

python – How can I convert serializer data into dict type in Django – Stack Overflow

python – How to serialize dict in Django? – Stack Overflow

Serializer fields for dictionaries and lists · Issue #560 · encode/django-rest-framework

serializer.data returns ReturnDict and OrderedDict instead of dict object. · Issue #2364 · encode/django-rest-framework

就是我要找的,此处希望是dict,实际上是OrderedDict

Serializing Django objects | Django documentation | Django

Serializers – Django REST framework

<code>serializer = CommentSerializer(comment)
serializer.data
# {'email': '[email protected]', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'}
</code>

好像是这么写的,应该没错才对

Can’t cache a ReturnDict. · Issue #2360 · encode/django-rest-framework

django serializer data  OrderedDict not dict

Python – Unable to modify the serializer.data dictionary in Django Rest Framework – Stack Overflow

python 2.7 – Django rest serializer.data is an empty OrderedDict() – Stack Overflow

再去看看输出:

<code>INFO|20180730 15:01:35|views:current_user:98|joinedFunctionGroupListSerializer=FunctionGroupSerializer(&lt;QuerySet [&lt;FunctionGroup: xxx剧本组&gt;]&gt;, many=True):
id = IntegerField(label='ID', read_only=True)
owner = CharField(source='owner.username')
name = CharField(max_length=128)
function = SerializerMethodField()
description = CharField(allow_blank=True, allow_null=True, max_length=128, required=False)
created_at = DateTimeField(read_only=True)
updated_at = DateTimeField(read_only=True)

</code>

INFO|20180730 15:01:35|views:current_user:100|serializedJoinedFunctionGroupList=[OrderedDict([(‘id’, 5), (‘owner’, ‘xx’), (‘name’, ‘xxx剧本组’), (‘function’, ‘script_function_group’), (‘description’, ‘xxx剧本组’), (‘created_at’, ‘2018-07-04 21:41:14’), (‘updated_at’, ‘2018-07-25 16:24:05’)])]

INFO|20180730 15:01:35|views:current_user:106|curJoinedFunctionGroup=OrderedDict([(‘id’, 5), (‘owner’, ‘xx’), (‘name’, ‘xxx剧本组’), (‘function’, ‘script_function_group’), (‘description’, ‘xxx剧本组’), (‘created_at’, ‘2018-07-04 21:41:14’), (‘updated_at’, ‘2018-07-25 16:24:05’)])

或许是list中每一个,都可以再去调用data去获取dict?

然后代码:

<code>        for curJoinedFunctionGroup in serializedJoinedFunctionGroupList:
            logger.info("type(curJoinedFunctionGroup)=%s", type(curJoinedFunctionGroup))
            logger.info("curJoinedFunctionGroup=%s", curJoinedFunctionGroup)
</code>

结果是:

<code>INFO|20180730 15:27:11|views:current_user:100|serializedJoinedFunctionGroupList=[OrderedDict([('id', 5), ('owner', 'xx'), ('name', 'xxx剧本组'), ('function', 'script_function_group'), ('description', 'xxx剧本组'), ('created_at', '2018-07-04 21:41:14'), ('updated_at', '2018-07-25 16:24:05')])]
INFO|20180730 15:27:11|views:current_user:106|type(curJoinedFunctionGroup)=&lt;class 'collections.OrderedDict'&gt;
INFO|20180730 15:27:11|views:current_user:107|curJoinedFunctionGroup=OrderedDict([('id', 5), ('owner', 'xxx'), ('name', 'xxx剧本组'), ('function', 'script_function_group'), ('description', 'xxx本组'), ('created_at', '2018-07-04 21:41:14'), ('updated_at', '2018-07-25 16:24:05')])
</code>

突然想到,好像是:

python中的dict,不是js中的dict,不能用:

someDict.someField

而应该是:

someDict[“someField”]

去试试,结果就好了。

【总结】

此处,其实:

<code>        allFunctionGroupList = FunctionGroup.objects.all()
        # function_group_names = list(allFunctionGroupList.values_list('name', flat=True))
        logger.info("allFunctionGroupList=%s", allFunctionGroupList)
        joinedFunctionGroupList = FunctionGroup.objects.filter(members=curUser)
        logger.info("joinedFunctionGroupList=%s", joinedFunctionGroupList)
        joinedFunctionGroupListSerializer = FunctionGroupSerializer(joinedFunctionGroupList, many=True)
        logger.info("joinedFunctionGroupListSerializer=%s", joinedFunctionGroupListSerializer)
        serializedJoinedFunctionGroupList = joinedFunctionGroupListSerializer.data
        logger.info("serializedJoinedFunctionGroupList=%s", serializedJoinedFunctionGroupList)

        curUserDict["joinedFunctionGroup"] = serializedJoinedFunctionGroupList
        isScriptFunctionGroupOwner = False
        ownedScriptFunctionGroup = None
        for curJoinedFunctionGroup in serializedJoinedFunctionGroupList:
            logger.info("type(curJoinedFunctionGroup)=%s", type(curJoinedFunctionGroup))
            logger.info("type(curUser)=%s", type(curUser))
            logger.info("curJoinedFunctionGroup=%s", curJoinedFunctionGroup)
</code>

此处的curJoinedFunctionGroup,已经是对应的dict,不过(其实,并且)是OrderedDict

而Python中获取dict的域(field,字段)值的话,不是支持:

js中的

someDict.someField

只能写成:

someDict[“someField”]

所以,只能写成:

curJoinedFunctionGroup[“function”]

而不是之前的:

curJoinedFunctionGroup.function

同时,之所以:

<code>                groupOwner = curJoinedFunctionGroup["owner"]
                logger.info("type(groupOwner)=%s", type(groupOwner))
                logger.info("groupOwner=%s", groupOwner)
                if groupOwner == curUser.username:
</code>

中的可以写成

curUser.username

是因为:

<code>type(curUser)=&lt;class 'apps.user.models.User'&gt;
</code>

即curUser此时是个class类,而类去访问属性/字段,是可以用:

someClass.someField

所以此处:

Django中,model对象去serialize后:

<code>
class FunctionGroup(TimestampedModel):
    TYPE_VALUE_ADMIN = "0"
    TYPE_VALUE_SCRIPT = "1"
    TYPE_NAME_ADMIN = "admin_function_group"
    TYPE_NAME_SCRIPT = "script_function_group"

    CHOICES = {
        (TYPE_VALUE_ADMIN, TYPE_NAME_ADMIN),
        (TYPE_VALUE_SCRIPT, TYPE_NAME_SCRIPT),
    }

    owner = models.ForeignKey(settings.AUTH_USER_MODEL,
                              on_delete=models.PROTECT,
                              related_name='user_function_group')
    name = models.CharField(null=False, blank=False, max_length=128)
    function = models.CharField(
        null=False, blank=False,
        # choices=FUNCTION_GROUP_CHOICES,
        choices=CHOICES,
        max_length=128,
        # default=FUNCTION_GROUP_CHOICES_DEFAULT
        default=TYPE_VALUE_SCRIPT
    )
    description = models.CharField(null=True, blank=True, max_length=128)
    members = models.ManyToManyField(User)


class FunctionGroupSerializer(serializers.ModelSerializer):
    owner = serializers.CharField(source='owner.username')
    function = serializers.SerializerMethodField()

    class Meta:
        model = FunctionGroup
        fields = ('id', 'owner', 'name', 'function', 'description',
                  'created_at', 'updated_at')
        read_only_fields = ('id', 'created_at', 'updated_at')

    def get_function(self, obj):
        return obj.get_function_display()
</code>

是可以通过:

<code>joinedFunctionGroupListSerializer = FunctionGroupSerializer(joinedFunctionGroupList, many=True)
serializedJoinedFunctionGroupList = joinedFunctionGroupListSerializer.data
for curJoinedFunctionGroup in serializedJoinedFunctionGroupList:
</code>

获得对应的单个的OrderedDict的curJoinedFunctionGroup的

只不过不要和Python中的class,或js中的dict

以为可以用somePythonClass.someField或someJsDict.someField

写成了:

somePythonDict.someField

否则当然会报错了。

转载请注明:在路上 » 【已解决】Django中数据serialize后不是字典对象而是OrderedDict的list

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.199 seconds, using 22.24MB memory