#python #django #django-rest-framework #django-serializer
#python #django #django-rest-framework #django-serializer
Вопрос:
Итак, я пытаюсь объединить список цветов и вернуть набор запросов сериализатору, однако serialzier, похоже, по какой-то причине не принимает это.
При запуске команд в оболочке я получаю:
>>> from django.contrib.postgres.aggregates import ArrayAgg
>>> from inventory.models import Product
>>> products = Product.objects.filter(category__parent__name__iexact='fliser').distinct().aggregate(colors_field=ArrayAgg('colors__name'))
>>> print(products)
{'colors_field': ['Beige', 'Grå', 'Hvit', 'Sort', 'Beige', 'Gul', 'Rød']}
Что является ожидаемым результатом.
Сериализатор структурирован следующим образом:
class ProductFiltersByCategorySerializer(serializers.ModelSerializer):
"""
A serializer to display available filters for a product lust
"""
colors = serializers.StringRelatedField(read_only=True, many=True)
class Meta:
model = Product
fields = ['colors']
Набор представлений выглядит следующим образом:
class ProductFiltersByCategory(generics.ListAPIView):
"""
This viewset takes the category parameter from the url and returns related product filters
"""
serializer_class = ProductFiltersByCategorySerializer
def get_queryset(self):
category = self.kwargs['category']
queryset = Product.objects.filter(category__parent__name__iexact=category).distinct().aggregate(colors_field=ArrayAgg('colors__name'))
return queryset
И соответствующая часть модели выглядит следующим образом:
class Product(models.Model):
...
colors = models.ManyToManyField(
ProductColor,
related_name='product_color'
)
...
Ошибка при попытке доступа к конечной точке 'str' object has no attribute 'colors'
.
Желаемого результата:
[
{
"colors": [
"Red",
"Orange",
],
},
]
Комментарии:
1. как вы передаете данные в сериализаторы? Покажите нам код.
2. @ArakkalAbu расширение ListAPIView обычно выполняет тяжелую работу, и указания
serializer_class = ProductFiltersByCategorySerializer
должно быть достаточно. Попытка выполнитьserializer = ProductFiltersByCategorySerializer(queryset, many=True) return Response(serializer.data)
в методе get_queryset возвращает ту же ошибку.3. Ваш
get_queryset()
метод возвращаетdict
объект. Во-первых, это не должно бытьdict
вторым, это должен быть объект, подобный списку4. Как бы я это сделал? Не могли бы вы привести мне пример? Я добавил желаемый результат в сообщение. Извините, совсем новичок в python / django.
Ответ №1:
Здесь вам не нужен ListAPIView
класс, используйте APIView
как
from rest_framework.views import APIView
from rest_framework.response import Response
class MyAPIView(APIView):
def get(self, request, *args, **kwargs):
category = kwargs['category']
agg_result = Product.objects.filter(
category__parent__name__iexact=category
).distinct().aggregate(colors_field=ArrayAgg('colors__name'))
return Response(agg_result)
Комментарии:
1. Есть ли какой-нибудь способ удалить дублирующиеся поля? На данный момент, если значение зарегистрировано в обоих экземплярах, будут отображаться две одинаковые строки:
{ "result": [ "Beige", "Red", "Yellow", "Beige", "White", "Gray", "Black" ] }
.2. idk, лучше вам задать новый вопрос.
3. Выяснив это, вы можете просто добавить
distinct=True
в метод ArrayAgg. Спасибо за всю помощь.
Ответ №2:
class ProductColorSerializer(serializers.ModelSerializer):
class Meta:
model = ProductColor
fields = '__all__'
class ProductFiltersByCategorySerializer(serializers.ModelSerializer):
"""
A serializer to display available filters for a product lust
"""
product_color = ProductColorSerializer(many=True)
class Meta:
model = Product
fields = ['product_color']
Комментарии:
1. Я не думаю, что эта настройка сгенерирует требуемый результат
2. этого не произойдет, потому что сериализатор получает объект dict , а не
QerySet