Фреймворк Django REST: обновление дает ошибку с вложенным сериализатором

У меня две модели

Модель пользователя Auth и профиль пользователя

UseProfile - это:

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='profile')
    name = models.CharField(_lazy(u'Name'), max_length=255)

Для чего я использую эти сериализаторы:

from rest_framework import serializers
from django.contrib.auth.models import User

from oneanddone.users.models import UserProfile

    class UserProfileSerializer(serializers.ModelSerializer):

        class Meta:
            model = UserProfile
            fields = ('name',)


    class UserSerializer(serializers.ModelSerializer):
        profile = serializers.RelatedField()

        class Meta:
            model = User
            fields = ('id', 'username', 'email', 'groups', 'profile')

Представления для обоих сериализаторов:

class UserListAPI(generics.ListCreateAPIView):
    """
    API endpoint used to get a complete list of users
    and create a new user.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer


class UserDetailAPI(generics.RetrieveUpdateDestroyAPIView):
    """
    API endpoint used to get, update and delete user data.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_field = 'email'

Вложенный сериализатор отлично работает для запросов на создание / удаление, но для таких запросов на обновление, как:

pdata = {"username":"testusername", "email":"[email protected]","profile":[{"name":"Changed Name"}]}

requests.patch('http://localhost:8000/api/v1/user/[email protected]/',data=json.dumps(pdata), headers={'Authorization':'Token bd876bfa04843c6ce1b82c84e27cd510f68dfbbd','Content-Type': 'application/json'}).text

Я получаю сообщение об ошибке, что объект «UserProfile» не повторяется. Отслеживание: http://pastebin.com/RA7JWFua

Можно ли выполнить подобное обновление с помощью только вложенного сериализатора? Также укажите специальный код, который мне нужно будет добавить, чтобы он заработал.


person bitgeeky    schedule 29.05.2014    source источник
comment
У вас когда-нибудь это работало? У меня похожая проблема   -  person SuperDuperTango    schedule 11.10.2014
comment
@SuperDuperTango Да, я получил его, внося некоторые изменения в сериализаторы и представления. Добавлен ответ, включая фактические фрагменты кода. Надеюсь, это поможет.   -  person bitgeeky    schedule 13.10.2014


Ответы (1)


Я добился этого, внося следующие изменения в сериализаторы и представления.

Сериализаторы для обеих моделей:

from django.contrib.auth.models import User

from rest_framework import serializers

from oneanddone.users.models import UserProfile


class UserProfileSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserProfile
        fields = ('name', 'username', 'privacy_policy_accepted')


class UserSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer(required=False, many=False)

    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'groups', 'profile')

Представления для обоих сериализаторов:

class UserDetailAPI(generics.RetrieveUpdateDestroyAPIView):
    """
    API endpoint used to get, update and delete user data.
    """
    lookup_field = 'email'
    queryset = User.objects.all()
    serializer_class = UserSerializer


class UserListAPI(generics.ListCreateAPIView):
    """
    API endpoint used to get a complete list of users
    and create a new user.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

И запрос на обновление можно записать в подобных строках, например:

# Change Profile Data(name, username, privacy_policy_accepted)
        changed_data = {'username': 'testname', 'email': '[email protected]',
                        'profile': {'name': 'Changed Test Name', 'username': 'testname123', 'privacy_policy_accepted': False}}
        response = self.client.patch(user_uri, changed_data, format='json')

Отказ от ответственности: все эти фрагменты кода теперь являются частью приложения, входящего в состав Mozilla, и выпущены под лицензией Mozilla.

Ссылки на исходный код можно найти здесь:

сериализаторы, Просмотры, Модульные тесты для обновления профиля

person bitgeeky    schedule 12.10.2014
comment
Я заставил его работать на основе этого ответа. Однако я не могу использовать этот код, потому что, если UserProfileSerializer имеет параметр fields, я получаю сбой при запуске. Я могу обойти это, сделав обратное и вместо этого используя exclude. Я зарегистрировал здесь проблему github.com/tomchristie/django-rest-framework / issues / 1943 - person SuperDuperTango; 13.10.2014