Как организовать связь категорий с подкатегориями в сериализаторе rest framework

Рейтинг: 0Ответов: 1Опубликовано: 20.01.2023

Я изучаю DRF и хотелось бы получить помощь. У меня есть модели с категориями и подкатегориями, мне бы хотелось выводить в сериализаторе при выборе категории выводились подкатегории относящиеся к этой категории. Такое можно организовать в сериализаторе?

Models:

class CategoryProduct(models.Model):
    """Основная категория"""
    name = models.CharField('Название категории', max_length=120)
    url = models.SlugField(max_length=160)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'Категория продукта'
        verbose_name_plural = 'Категории продуктов'


class SubCategoryProduct(models.Model):
    """Подкатегория"""
    name = models.CharField('Название подкатегории', max_length=120)
    category = models.ForeignKey(CategoryProduct, on_delete=models.CASCADE, verbose_name='Категория подкатегория')
    url = models.SlugField(max_length=160)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'Подкатегория продукта'
        verbose_name_plural = 'Подкатегории продуктов'

serializer:

class CategorySerializers(serializers.ModelSerializer):

    class Meta:
        model = models.CategoryProduct
        fields = ('name',)


class SubCategoryProductSerializers(serializers.ModelSerializer):
    # category = CategorySerializers()
    class Meta:
        model = models.SubCategoryProduct
        fields = ('name', 'category')

Сейчас получается какую бы я категорию не выбирал, в подкатегориях получаю весь список. Или это реализуется на frontend. Я пытаюсь на текущий момент реализовать это в форме rest framework при отправке POST запроса.


Как я понял это нужно организовать на Frontend.

models

class CategoryProduct(models.Model):
    """Основная категория"""
    name = models.CharField('Название категории', max_length=120)
    url = models.SlugField(max_length=160)

class SubCategoryProduct(models.Model):
    """Подкатегория"""
    name = models.CharField('Название подкатегории', max_length=120)
    category = models.ForeignKey(CategoryProduct, on_delete=models.CASCADE, verbose_name='Категория подкатегория')
    url = models.SlugField(max_length=160)

class Product(models.Model):
    """Модель объявлений товаров"""
    category = models.ForeignKey(CategoryProduct, on_delete=models.CASCADE, verbose_name='Категория адс')
    sub_category = models.ForeignKey(SubCategoryProduct, on_delete=models.CASCADE, verbose_name='Подкатегория адс')
    name = models.CharField(verbose_name='Название объявления', max_length=160)

Ответы

▲ 0

Конечно это надо реализовывать на DRF. Задача сводится к тому, что бы отфильтровать SubCategoryProduct по связям с ForeignKey(CategoryProduct. Вам потребуется переписать serializer с использованием SerializerMethodField(). В Вашем случае код будет примерно таким:

class SubCategoryProductSerializer(serializers.ModelSerializer):

    class Meta:
        model = SubCategoryProduct
        fields = '__all__'


class CategorySerializer(serializers.ModelSerializer):
    sub_category = serializers.SerializerMethodField()

    class Meta:
        model = CategoryProduct
        fields = ('name', 'sub_category')

    def get_sub_category(self, obj):
        queryset = SubCategoryProduct.objects.filter(category=obj)
        return [SubCategoryProductSerializer(q).data for q in queryset]

Ваш View должен выглядеть примерно так:

class SubCategoryProductCreateView(APIView):

    def post(self, request):
        serializer = SubCategoryProductSerializer(
            data=request.data,
            )
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)