Джанго ДРФ | Изменить поле родительской модели при создании дочерней модели - PullRequest
0 голосов
/ 06 марта 2019

У меня есть модель User и другая модель Admin, которая имеет отношение OneToOne с моделью User.

Я пытаюсь изменить поле в модели User во время создания модели Admin.

Вот мой Serializer для модели администратора:

class AdminSerializer(serializers.ModelSerializer):
    """A Serizlier class for vendor """

    user = UserSerializer()

    class Meta:
        model = models.Admin
        fields = ('user', 'first_name', 'last_name', 'dob', 'gender')

        # This didn't work, also user_type is a field in User model and not Admin model
        read_only_fields = ('user_type',)


    def create(self, validated_data): # override this method <<<
        """
        Since the "user" is a read_only field, the validated data doesn't contain it.
        """

        # Line that causes the error. Trying to modify User model field
        validated_data['user_type'] = constants.Constants.ADMIN
        return super().create(validated_data)

, но я получаю ошибку:

Метод .create() по умолчанию не поддерживает записи вложенных полей.Напишите явный .create() метод для сериализатора letzbargain_api.serializers.AdminSerializer или установите read_only=True для вложенных полей сериализатора

Как это исправить?

1 Ответ

2 голосов
/ 06 марта 2019

Если я правильно понимаю вашу проблему, вы хотите создать Admin, но хотите оставить Admin user * user_type только для чтения.

Для этого у вас естьчтобы убедиться, что user_type доступен только для чтения в указанном вами сериализаторе пользователя AdminSerializer.Например, я пишу новый сериализатор:

class AdminUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.User
        fields = ('foo', 'bar', 'user_type')
        read_only_fields = ('user_type',)

Теперь используйте его в своем AdminSerializer:

class AdminSerializer(serializers.ModelSerializer):
    user = AdminUserSerializer() # make sure user_type is read-only in whatever serializer you specify here

    class Meta:
        model = models.Admin
        fields = ('user', 'first_name', 'last_name', 'dob', 'gender')

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        user = models.User.objects.create(**user_data, user_type=constants.Constants.ADMIN)
        admin = models.Admin.objects.create(user=user, **validated_data)
        return admin
...