Как я могу исправить мое представление REST для ИСПРАВЛЕНИЯ и сериализации обновлений для arrayField() в моей модели?

#python #django #django-rest-framework #django-views

#питон #джанго #django-rest-фреймворк #django-views

Вопрос:

У меня есть представление, которое используется для обновления поля в моей модели. Это представлено следующим образом: stock_list = ArrayField(models.CharField())

Каждое значение в arrayField разделяется запятыми.

Я использовал пользовательский метод сериализатора, позволяющий моему бэкэнду разделять элементы в моем ПАТЧЕ obj запятыми.

  • serializers.py :
 class StringArrayField(ListField):
    """
    String representation of an array field.
    """
    def to_representation(self, obj):
        obj = super().to_representation(obj)
        # convert list to string
        return ",".join([str(element) for element in obj])

    def to_internal_value(self, data):
        data = data.split(",")  # convert string to list
        return super().to_internal_value(self, data)


class StockListSerializer(serializers.ModelSerializer):
    stock_list = StringArrayField()

    class Meta:
        model = Bucket
        fields = ("stock_list",)
 

Ниже приведен мой вид, который я использую, URL-адреса связаны правильно, однако я неправильно настраиваю свой вид:

  • view.py:
 class EditBucketSymbols(generics.RetrieveUpdateAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = StockListSerializer

    def get_queryset(self):
        return Bucket.objects.all()

    def get_object(self, queryset=None, **kwargs):
        item = self.kwargs.get('pk')
        return get_object_or_404(Bucket, pk=item)

    def patch(self, request, *args, **kwargs):
        item = BucketDetail.get_object(self)
        data = request.data
        item.stock_list = data.get("stock_list", item.stock_list)
        serializer = StockListSerializer(data=item.stock_list,  partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 

Вот ошибка ИСПРАВЛЕНИЯ, которую я получаю:

 {
    "non_field_errors": [
        "Invalid data. Expected a dictionary, but got str."
    ]
}
 

Я не уверен, почему мое представление ожидает словаря, я только хочу, чтобы пользователи ИСПРАВЛЯЛИ arrayfield, известное как stock_list , с данными, которые они вводят.

Буду признателен за любую помощь в отладке здесь, чтобы мое представление ИСПРАВЛЕНИЙ работало должным образом, как и ожидалось.

Комментарии:

1. Пожалуйста, помогите показать ваш запрос данных

Ответ №1:

Во-первых, вам нужно изменить super() метод, вызывающий to_internal_value(...) метод (вы неправильно его вызывали)

 class StringArrayField(serializers.ListField):
    def to_representation(self, obj):
        obj = super().to_representation(obj)
        return ",".join([str(element) for element in obj])

    def to_internal_value(self, data):
        data = data.split(",")
        return super().to_internal_value(data) # update here 

а затем используйте generics.RetrieveUpdateAPIView «как есть», потому что вам не нужны какие-либо изменения в представлении (по крайней мере, минимальный случай, который вы указали в OP)

Итак, ваше представление станет,

 class EditBucketSymbols(generics.RetrieveUpdateAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = StockListSerializer
    queryset = Bucket.objects.all() 

Это позволит вам легко обновлять данные и иметь в виду, что DRF ожидает данные в следующем формате,

 {
    "stock_list":"this,is,patch,request,test"
}
 

Пример скриншота результата
Пример скриншота результата

Комментарии:

1. Ах, это здорово @JPG! Большое спасибо за помощь и пояснения, которые вы добавили к этому сообщению.