create() argument after ** must be a mapping, not

2019-02-20 13:44发布

I'm attempting to do a nested write using the following serializer -

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('company', 'is_admin', 'last_modified', 'uuid')

class UserSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer()
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'profile')

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        user = User.objects.create(**validated_data)
        for profile_data in profile_data:
            UserProfile.objects.create(user=user, **profile_data)
        return user

But after doing a post I get the following traceback -

Traceback:
File "/opt/enterpass_app/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/opt/enterpass_app/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)
File "/opt/enterpass_app/lib/python2.7/site-packages/rest_framework/viewsets.py" in view
  87.             return self.dispatch(request, *args, **kwargs)
File "/opt/enterpass_app/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  466.             response = self.handle_exception(exc)
File "/opt/enterpass_app/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  463.             response = handler(request, *args, **kwargs)
File "/opt/enterpass_app/lib/python2.7/site-packages/rest_framework/mixins.py" in create
  21.         self.perform_create(serializer)
File "/opt/enterpass_app/lib/python2.7/site-packages/rest_framework/mixins.py" in perform_create
  26.         serializer.save()
File "/opt/enterpass_app/lib/python2.7/site-packages/rest_framework/serializers.py" in save
  180.             self.instance = self.create(validated_data)
File "/opt/enterpass/core/serializers.py" in create
  20.             UserProfile.objects.create(user=user, **profile_data)

Exception Type: TypeError at /api/users/
Exception Value: create() argument after ** must be a mapping, not unicode

I'm following the documentation here http://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers verbatim so not sure what I'm missing. Possibly that I'm doing a OneToOneField on the User not a ForeignKey like the example?

edit - want to add that even though I get the above Traceback it does still post to User but not to User Profile.

1条回答
We Are One
2楼-- · 2019-02-20 14:30

For anyone doing a OneToOne mapping on a key this is the correct code -

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('company', 'is_admin', 'last_modified', 'uuid')

class UserSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer()
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'profile')

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        user = User.objects.create(**validated_data)
        UserProfile.objects.create(user=user, **profile_data)
        return user

Note that the following is removed for profile_data in profile_data:

Reason being there isn't multiple values.

查看更多
登录 后发表回答