#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! Большое спасибо за помощь и пояснения, которые вы добавили к этому сообщению.