How to use a ManyToMany field in JsonResponse?

Issue

I have this model in Django:

class Post(models.Model):
    poster = models.ForeignKey('User', on_delete=models.CASCADE, related_name='posts')
    body = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)
    likers = models.ManyToManyField('User', blank=True, null=True, related_name='liked_posts')
    likes = models.IntegerField(default=0)

    def serialize(self):
        return {
            'id': self.pk,
            'poster': self.poster.username,
            'body': self.body,
            'timestamp': self.timestamp.strftime('%b %d %Y, %I:%M %p'),
            'likes': self.likes
        }

It works but when I try to add likers to it, I get an error which says I can’t use manytomany fields. How can I do such thing?

I fetch it in JavaScript like this:

fetch('/posts')
    .then(response => response.json())
    .then(data => {
        console.log(data);
    });

Using this view:

def posts_view(request):
    posts = Post.objects.all()
    posts = posts.order_by('-timestamp').all()
    return JsonResponse([post.serialize() for post in posts], safe=False)

Solution

You don’t have to serialize your models manually, i.e. defining serialize(self) method for each model. Try to use django-rest-framework, everything is already made for you.

  1. Define serializers for your models in serializers.py.
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"


class PostSerializer(serializers.ModelSerializer):
    poster = UserSerializer()
    likers = UserSerializer(many=True, allow_null=True, default=None)

    # if you want short info about likers (list of ids), use snippet below
    # likers = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), many=True)

    class Meta:
        model = Post
        fields = "__all__"
  1. And then in your view:
def posts_view(request):
    posts = Post.objects.all().order_by('-timestamp')
    data = PostSerializer(posts, many=True).data
    return JsonResponse(data)

Answered By – Nikita

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published