DRF: универсальный способ добавить дополнительную информацию в request.data - PullRequest
0 голосов
/ 16 февраля 2019

Я нахожусь в ситуации, когда у меня есть конечная точка samples, которая представляет модель sample через ModelViewSet.

Моя цель состоит в том, чтобы, когда пользователь POST сопоставлял эту конечную точку с данными

как

{
    "a":1,
    "b":2 ,
    "c":3
}

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

Этого нельзя сделать просто путем доступа к request.data, поскольку это QueryDict, который является неизменным.

Кроме того, яЯ не могу добиться этого в методе perform_create(), поскольку данные, которые я могу ввести, критичны к проверке.

В настоящее время я застрял со следующим решением, которое требует от меня ПЕРЕЗАПИСАТЬ полный метод create():

class MyViewSet(viewsets.ModelViewSet):
    queryset = Sample.objects.all()
    serializer_class = MSampleSerializer
    name = "samples"

    def add_info(self, request):
        ...
        <acquire_info>
        ...
        data = request.data.dict()
        data["s"] = <info1>
        data["r"] = <info1>
        data["t"] = <info1>
        return data


    def create(self, request, *args, **kwargs):
        data = self.add_info(request)
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(
            serializer.data, status=status.HTTP_201_CREATED, headers=headers
        )
  1. Существует ли общий способ редактирования request.data перед вызовом любого метода действия, такого как create() или put(),?

  2. Если нет 1.);Есть ли другая возможность?

Заранее спасибо.

1 Ответ

0 голосов
/ 16 февраля 2019

Вы можете использовать методы сериализатора .to_representation() или .to_internal_value(), если не хотите каждый раз переписывать весь вид.

И так как вы также хотите проверить данные, .to_representation() может быть подходящим способом.

Из документов:

Если вам нужночтобы изменить поведение сериализации или десериализации класса сериализатора, вы можете сделать это, переопределив методы .to_representation() или .to_internal_value().

.to_representation(self, obj) берет экземпляр объекта, который требует сериализации, и должен вернуть примитивпредставление.Как правило, это означает возвращение структуры встроенных типов данных Python.Точные типы, которые могут быть обработаны, будут зависеть от классов рендеринга, которые вы настроили для своего API.

Пример:

def to_representation(self, instance):
    """Convert `username` to lowercase."""
    ret = super().to_representation(instance)
    ret['username'] = ret['username'].lower()
    return ret

См. Расширенное использование сериализатора: Переопределение сериализациии десериализация поведения

...