I have taken a look around, and I didn't find an answer to this question.
Serializers.py
class PostSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Post
fields = ['title', 'body', 'comments', 'user', 'date']
class CommentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Comment
fields = ['body', 'user', 'date']
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['id', 'user']
Models.py
class Post(models.Model):
# Children
comments = models.ManyToManyField('Comment', blank=True)
# Content
title = models.TextField(default="-->Title here<--")
body = models.TextField(default="-->Body here<--")
# About
user = models.ForeignKey(User)
date = models.DateTimeField(auto_now=True)
object_id = models.PositiveIntegerField(default=0)
content_type = models.ForeignKey(ContentType, default=0)
content_object = fields.GenericForeignKey()
def __str__(self):
return str(self.title)
class Comment(models.Model):
comments = models.ManyToManyField('Comment', blank=True)
# Content
body = models.TextField(default="-->Body here<--")
# About
user = models.ForeignKey(User)
date = models.DateTimeField(auto_now=True)
object_id = models.PositiveIntegerField(default=0)
content_type = models.ForeignKey(ContentType, default=0)
content_object = fields.GenericForeignKey()
def __str__(self):
return str(self.body)
Views.py
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
class CommentViewSet(viewsets.ModelViewSet):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
def index(request):
return render(request, 'index.html', [])
The index template is a "homepage" that loads the latest posts. Under each post, I'm showing the comments. In the JSON those are links, and I found out how to load them trougth the links (so it's working).
Someone told me that instead of doing it this way, I should make it "load" the comments in the backend, and send them together with the posts (the data, not links). He told me to take a look into: http://www.django-rest-framework.org/api-guide/filtering/#overriding-the-initial-queryset
I can't really figure it out.
How do I get the data, insted of links for the ManyToManyField?
To unfold all the related data one level deep you can use depth
param:
class PostSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Post
fields = ['title', 'body', 'comments', 'user', 'date']
depth = 1
This will replace post.user
and post.comments
ids with actual records. depth=2
will also unfold post.comments.user
. If you want to selectively pull post.comments
only one level deep and not post.user
:
class PostSerializer(serializers.HyperlinkedModelSerializer):
comments = CommentSerializer(many=True) #has to be declared higher above
class Meta:
model = Post
fields = ['title', 'body', 'comments', 'user', 'date']
If on top you want to have post.comments.user
unfolded, need to either put depth=1
into existing comment serializer or create a new serializer with unfolded users just for this view, similar to examples above.
Also make sure you are using prefetch_related
on your queryset or the performance will take a serious hit, like:
Post.objects.all().prefetch_related('comments', 'comments__user')