I want to nest a model into the Serialiazer. Category' object has no attribute 'brand_set'

I want to nest a model into the serializer. Like on list of Category, there should be fields from Brand model, But I m getting error by on setting this way ?

models.py

class Category(models.Model):
    title = models.CharField(max_length=50)
    timestamp = models.DateTimeField(auto_now_add=True)
    #....


class Brand(models.Model):
    title = models.CharField(max_length=50)
    category = models.ForeignKey(
        Category, blank=True, null=True, on_delete=models.SET_NULL, related_name="category")
    #....

Serializers

class CategorySerializerNested(serializers.ModelSerializer):
    brands = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Category
        fields = '__all__'

    def get_brands(self, obj):
        brands = obj.brand_set.all() #this thin popping error how to fix that....
        serializer = BrandSerializerNested(brands, many=True)
        return serializer.data


class BrandSerializerNested(serializers.ModelSerializer):
    products = serializers.SerializerMethodField(read_only=True)

    def get_products(self, obj):
        products = obj.product_set.all()
        serializer = ProductSerializer(products, many=True)
        return serializer.data

    class Meta:
        model = Brand
        fields = '__all__'

View.py

@api_view(['GET'])
def getCategoryWithBrands(request, pk):
    category = Category.objects.get(id=pk)
    serializer = CategorySerializerNested(category, many=False)
    return Response(serializer.data)

url.py

path('nested/<str:pk>/', views.getCategoryWithBrands,
         name="category-with-brands"),

Error:

AttributeError: 'Category' object has no attribute 'brand_set'
[02/Feb/2022 03:24:49] "GET /api/v1/categories/nested/1/ HTTP/1.1" 500 125121 

I’m sure im doing something illogical but i dont know now, please help me to fix this , if there’s any better way to do that please also help there as well. Thanks

>Solution :

Since you specified related_name='category', you obtain the related Brands with:

def get_brands(self, obj):
    brands = obj.category.all()
    serializer = BrandSerializerNested(brands, many=True)
    return serializer.data

But that does not make much sense: the related_name=… [Django-doc] specifies the name of the relation in reverse so obtaining the Brands for a given Category, you thus can rename these to:

class Brand(models.Model):
    category = models.ForeignKey(
        Category,
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        related_name='brands'
    )
    #…

and work with a subserializer:

def get_brands(self, obj):
    brands = obj.brands.all()
    serializer = BrandSerializerNested(brands, many=True)
    return serializer.data

or just define BrandSerializerNested first and use:

class CategorySerializerNested(serializers.ModelSerializer):
    brands = serializers.BrandSerializerNested(read_only=True)

    class Meta:
        model = Category
        fields = '__all__'

Leave a Reply