0

So, I'm trying to use Django Rest Framework for my project. I have two models Category and Content to be serialized, as below:
views.py

class Category(models.Model):
    category_name = models.CharField(max_length = 20)

    def __str__(self):
        return self.category

class Content(models.Model):
    category = models.ManyToManyField(Category)
    body = models.TextField(blank=True, null=True)
    created_at = models.DateField(auto_now_add=True, null=True)
    
    def __str__(self):
        return self.created_at

serializers.py

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ['category_name']

class ContentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Content
        fields = [
            'category', 'body', 'created_at',
            ]

Now the problem is, the JSON object returned has the id of each object in Category, NOT the category_name. So when I console.log in my front-end, I get (for example) [1, 4, 8] but what I need is (for example) ['Wine', 'Beer', 'Whiskey'].

How do I make that possible? Thanks in advance :)

Ryan
  • 199
  • 1
  • 9
  • When you're returning your array from the backend, instead of returning the number, maybe return the array[num] ? I don't really know how your views work, but I think the issue is that you're just returning pure numeric data instead of referencing what those values are? – jasonmzx Mar 13 '21 at 23:12

3 Answers3

0

arif almost got it but he forgot to reference which field it is going to filter the ManyToMany

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ("id", "name", ) # pk is required as it is used by serializer to match the ManyToMany data for each row on Model.Content

class ContentSerializer(serializers.ModelSerializer):
    categories = CategorySerializer(many=true, source='category' ) 
    
    class Meta:
        model = Content
        fields = ("id", "categories", "body", )

Notice I just added source='category' this

source='category' is from Model.Content I just preserve the variable name used here.

so it knows which "CategorySerializer" is being referred to.

-1

You need to check out StringRelatedField I think.

https://www.django-rest-framework.org/api-guide/relations/#stringrelatedfield

You can serialize related fields as defined in __str__ method in your model.


And also you can serialize your every item in that field like:

{ id: 1, name: 'category name' }

You need to check nested serializers for done that:

https://www.django-rest-framework.org/api-guide/relations/#nested-relationships

For example:

You need something like nested serializer, you can check it from there:

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ("id", "name", ) # You can specify whatever fields you want here.

class ContentSerializer(serializers.ModelSerializer):
    category = CategorySerializer() # many=True if you want
    
    class Meta:
        model = Content
        fields = ("id", "category", "body", )

I think what you want is StringRelatedField, return field that yo. The second one, nested relationships was extra

arif
  • 441
  • 1
  • 6
  • 13
-1

You can make a read only field in serializer and set the source as follows:

class ContentSerializer(serializers.ModelSerializer):
    
    category_name = serializers.CharField(source='category.category_name', 
                    read_only=True)
    class Meta:
        model = Content
        fields = [
            'category', 'body', 'created_at',
            ]

You can then bind category_name from JSON response with your frontend.

Neeraj
  • 975
  • 4
  • 10