Метод передачи переменных URL из класса APIView в сериализатор - PullRequest
0 голосов
/ 21 апреля 2020

Мне нужно получить переменные, переданные в URL, и передать их в сериализатор для дальнейшей обработки. Я знаю, как обрабатывать эти переменные в представлениях, но не в сериализаторе.

urls.py

path('upload_excel_rfi/<str:rfiid>/<int:vendor>/<int:analyst>/', UploadElementFromExcelFile.as_view()

views.py

class UploadElementFromExcelFile(APIView):
    serializer_class = ElementCommonInfoSerializer

def post(self, request, *args, **kwargs):
    # GET VARIABLES
    rfiid = kwargs.get('rfiid')
    vendor = kwargs.get('vendor')
    analyst = kwargs.get('analyst')
    data = request.data  # response data is list of dict
    try:
        # implement transaction  - if exception appear during for loop iteration none data save to DB
        with transaction.atomic():
            ....some logic
            serializer.is_valid(raise_exception=True)
            serializer.save()
    except ValidationError:
        return Response({"errors": (serializer.errors,)},
                        status=status.HTTP_400_BAD_REQUEST)
    else:
        return Response(request.data, status=status.HTTP_200_OK)

serializer.py

class ElementCommonInfoSerializer(serializers.ModelSerializer):

    class Meta:
        model = Elements
        fields = ("...")

    def create(self, validated_data):
        .....
        return self

Я нашел упоминание def get_serializer_context(self), но, как я понял, этот метод не используется с APIView. Не могли бы вы рассказать мне, как правильно передавать дополнительные переменные? Теперь я расскажу о способе добавления дополнительной переменной context= {} в сериализатор

context = {"rfiid": kwargs.get('rfiid')}
serializer = BlaBlaSerializer(data=data, context=context)

Но мне интересно, есть ли другой, более DRY -подходящий способ.

1 Ответ

1 голос
/ 21 апреля 2020

serializer_class ничего не делает в APIView DRF. Вы можете передать дополнительный контекст сериализатору следующим образом:

serializer = ElementCommonInfoSerializer(data=data, context={'request': request})

и затем в вашем сериализаторе.

class ElementCommonInfoSerializer(serializers.ModelSerializer):

    class Meta:
        model = Elements
        fields = ("...")

    def create(self, validated_data):
        request = self.context.get('request')
        ...
        return self
...