在:
【已解决】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
就是我要找的,此处希望是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(<QuerySet [<FunctionGroup: xxx剧本组>]>, 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)=<class 'collections.OrderedDict'> 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)=<class 'apps.user.models.User'> </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