Django DRF добавляет request.user в модельный сериализатор - PullRequest
0 голосов
/ 06 апреля 2019

Я использую django rest Framework, и у меня есть объект, создаваемый с помощью набора моделей, и сериализатор моделей. Это представление доступно только аутентифицированным пользователям, и объект должен установить свое поле 'uploaded_by', чтобы быть этим пользователем.

Я прочитал документы и пришел к выводу, что это должно работать

Viewset:

class FooViewset(viewsets.ModelViewSet):
    permission_classes = [permissions.IsAdminUser]
    queryset = Foo.objects.all()
    serializer_class = FooSerializer

    def get_serializer_context(self):
        return {"request": self.request}

сериализатору:

class FooSerializer(serializers.ModelSerializer):
    uploaded_by = serializers.PrimaryKeyRelatedField(
        read_only=True, default=serializers.CurrentUserDefault()
    )

    class Meta:
        model = Foo
        fields = "__all__"

Однако это приводит к следующей ошибке:

django.db.utils.IntegrityError: NOT NULL constraint failed: bar_foo.uploaded_by_id

Что говорит о том, что «uploaded_by» не заполняется сериализатором.

Исходя из моего понимания документов, это должно было добавить поле к проверенным данным из сериализатора, как часть метода create.

Очевидно, я что-то неправильно понял!

1 Ответ

2 голосов
/ 06 апреля 2019

Проблема заключается в атрибуте read_only в вашем поле uploaded_by:

Поля только для чтения включены в выходные данные API, но не должны включаться во входные данные при создании илиОперации обновления.Любые поля 'read_only', которые неправильно включены во входные данные сериализатора, будут игнорироваться.

Установите для этого параметра значение True, чтобы гарантировать, что поле используется при сериализации представления, но не используется при создании или обновлении экземпляра во времядесериализация.

Источник

В основном он используется для отображения представления объекта, но исключается при любом обновлении и процессе создания.

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

class FooSerializer(serializers.ModelSerializer):

    uploaded_by = serializers.PrimaryKeyRelatedField(read_only=True)

    def create(self, validated_data):
        foo = Foo.objects.create(uploaded_by=self.context['request'].user,
                                 **validated_data)
        return foo
...