Массовая вставка в Django Rest Framework JSONAPI - PullRequest
0 голосов
/ 17 февраля 2020

Я реализую DRFJSonAPI API : https://django-rest-framework-json-api.readthedocs.io/en/stable/index.html

Однако я застрял при попытке реализовать массовую вставку, похоже, что Спецификация JSONAPI ничего не упоминает об этом. Я нашел только это, ссылаясь на это как на экспериментальную функцию: https://springbot.github.io/json-api/extensions/bulk/

и, похоже, она не реализована DRF JSONAPI

Я пробовал несколько подходов: от базового c определения новой @action, определенной в моем наборе, до простого добавления DRF api_view и перехода оттуда. Но похоже, что мой сериализатор неправильно понимает данные и возвращает пустой словарь.

Мои сериализаторы:


from rest_framework_json_api import serializers, relations, views

class VideoScriptRowSerializer(serializers.ModelSerializer):

    included_serializers = {
        'video': 'videos.serializers.VideoOnDemandSerializer',
    }

    class Meta:
        model = VideoScriptRow
        fields = (
            'video_id',
            'index',
            'character',
            'guessed',
            'is_locked',
            'loop',
            'text',
            'time_start',
        )


class VideoOnDemandSerializer(serializers.ModelSerializer):
    script_rows = relations.ResourceRelatedField(
        queryset=VideoScriptRow.objects,  # queryset argument is required
        required=False,
        many=True,
    )
    included_serializers = {
        'script_rows': 'videos.serializers.VideoScriptRowSerializer',
    }

    class Meta:
        model = VideoOnDemand
        fields = (
            'title',
            'workflow_status',
            'initial_offset',
            'video_offset',
            'video_input',
            'thumbnail_url',
            'transcript_uri',
            'created_at',
            'script_rows',
        )
        read_only_fields = ('created_at', 'workflow_status')

Мои просмотры:


    from rest_framework_json_api.views import ModelViewSet, RelationshipView

    class VideoScriptRowViewSet(ModelViewSet):
        queryset = VideoScriptRow.objects.all()
        serializer_class = VideoScriptRowSerializer


    class VideoOnDemandViewSet(ModelViewSet):
        permission_classes = [IsAuthenticated]
        queryset = VideoOnDemand.objects.all()
        serializer_class = VideoOnDemandSerializer

Основываясь на документации DRF, кажется, что вам просто нужно передать many = True экземпляру сериализатора для массового создания, но все примеры, которые я нашел, были о сериализации, чтобы показать список объектов, а не о десериализации данных исходящий из POST.

Я также пытался напрямую наследовать от ListSerializer и создавать ViewSet только для этого действия ... все еще ничего в моем request.data, когда я использую список элементов

Моей последней попыткой было просто добавить декоратор @api_view, так как я думал, что он будет неуязвим для DRF JSONAPi, но все равно ничего в моей request.data

реализации api_view:

@api_view(['post'])
def update_script_rows(request):
    serializer = VideoScriptRowSerializer(data=request.data, many=True)  # request.data is empty here
    serializer.is_valid(raise_exception=True)
    # Here goes the bulk insertion
    return Response(status=status.HTTP_201_CREATED)

Тестовая реализация, которая вызывает представление:

    def test_update_script_rows(self):
        self.client.login(email='foobar@invalid.com', password='secretpassword')
        url = reverse('update-script-rows')

        response = self.client.post(
            url,
            {
                'data': [{
                    'type': 'VideoScriptRow',
                    'attributes': {
                        'index': 1,
                        'video_id': self.v1.id,
                        'character': 'johndoe',
                        'text': 'hello, world2',
                    }
                }],
            },
            format='vnd.api+json'
        )

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

Если это действие выполняется на VideoScriptRowViewSet, я могу увидеть данные в request.data, когда это одиночное объект, но когда это список, я ничего не вижу. Если я делаю это на @api_view, я получаю сообщение об ошибке: rest_framework_json_api.exceptions.Conflict: The resource object's type (VideoScriptRow) is not the type that constitute the collection represented by the endpoint (UpdateScriptRows). Даже после изменения базового класса моего сериализатора с DRFJSONAPI на DRF, где-то еще есть ссылки на DRFJSONAPI, которые я не вижу.

Есть идеи, как мне легко добиться этого массового создания на DRFJSONAPi? Моя лучшая идея сейчас состоит в том, чтобы избавиться от JSONAPI и делать все на обычном DRF, но я хотел бы сохранить структуру JSONAPI, если это возможно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...