How to get value of ManyToMany field rather than their ids?

Question:

I have three models, as shown below:

class TagsModel(models.Model):
    title = models.CharField(max_length=200)

    def __str__(self):
        return self.title
 
class ImagesModel(models.Model):
    title = models.CharField(max_length=500, default='image')
    image_cdn = models.TextField(null=True, blank=True)
    image = models.ImageField(upload_to='articles/images/', null=True, blank=True)
    timestamp = models.DateTimeField(auto_now=True)
    update = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.title


class ArticlesModel(models.Model):
    title = models.CharField(max_length=1000)
    category = models.CharField(max_length=40, choices=category_choices, default=('General', 'General'))
    summary = models.TextField(blank=False, null=True, max_length=5000)
    tags = models.ManyToManyField(TagsModel, blank=True)
    image = models.ImageField(blank=True, null=True, upload_to='articles/article-image/')
    image_cdn = models.TextField(blank=True, null=True)
    image_src = models.ForeignKey(ImagesModel, related_name='Image_cdn',  on_delete=models.PROTECT, null=True)
    images = models.ManyToManyField(ImagesModel, blank=True) 
    json = models.JSONField(null=True, blank=True)
    html = models.TextField(blank=True, null=True)
    is_published = models.BooleanField(default=False)
    update = models.DateTimeField(auto_now_add=True)
    timestamp = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('articles:article_detail', kwargs={'article_id': self.id})


And in the view.py

class ArticlesView(APIView):

    def get(self, request):
        articles_list = ArticlesModel.objects.all()
        images_list = ImagesModel.objects.all()
        images_serializer = ImagesSerializer(images_list, many=True)
        articles_serializer = ArticlesListSerializer(articles_list, many=True)
        return Response({
            'images':images_serializer.data,
            'articles':articles_serializer.data
        })


So when I send request I get results like this:
enter image description here

The problem here is that I get the ids of Images and tags and not the objects themselves!
I am asking if there’s a way in django/DRF to get the objects (images, tags) included with the queries of Articles and not only their ids?

Answers:

Solution

class ProductSerializer(serializers.ModelSerializer):
    cate = serializers.SerializerMethodField('get_cate')

    def get_cate(self,obj):
        return [cate.name for cate in obj.cate.all()]
        
    class Meta:
        model = ProductModel 
        fields = "__all__"

Response output

[
    {
        "id": 1,
        "cate": [
            "Category5",
            "Category6"
        ],
        "name": "Apple",
        "price": "12.00",
        "released_at": "2022-10-18T13:16:01Z"
    },
    {
        "id": 2,
        "cate": [
            "Category1",
            "Category2",
            "Category3"
        ],
        "name": "Kiwi",
        "price": "20.00",
        "released_at": "2022-10-18T13:16:01Z"
    },
    {
        "id": 3,
        "cate": [
            "Category2",
            "Category4",
            "Category5",
            "Category6"
        ],
        "name": "Tomato",
        "price": "25.00",
        "released_at": "2022-10-18T13:16:01Z"
    }
]

This is called serializer relations, You can find the solution to your issue & more suggestions in this article https://www.django-rest-framework.org/api-guide/relations/

Answered By: Ali Al-Janabi