Reputation: 337
Hello all I want to hide certain json data from passing through if it doesn't meet a condition in django rest framework, like I have a comment model and serializer, and I don't want the replies to pass through as comments since I have another field for replies which is nested along with the respective comments.
These are the serializers:
class CommentCreateSerializer(serializers.ModelSerializer):
content = serializers.CharField()
reply_id = serializers.PrimaryKeyRelatedField(source='reply',queryset=Comment.objects.all(),
write_only=True, required=False)
user = serializers.ReadOnlyField(source="user.username")
class Meta:
model = Comment
fields = ['id', 'user', 'content', 'reply_id', 'timestamp']
class CommentSerializer(serializers.ModelSerializer):
content = serializers.CharField()
reply_id = serializers.PrimaryKeyRelatedField(source='reply',queryset=Comment.objects.all(),
required=False)
user = serializers.ReadOnlyField(source="user.username")
replies = CommentCreateSerializer(many=True, read_only=True)
class Meta:
model = Comment
fields = ['id', 'user', 'content', 'replies', 'reply_id', 'timestamp']
This is the current json response:
"count": 5,
"next": null,
"previous": null,
"results": [
{
"id": 2,
"user": "testuser2",
"content": "comment test!",
"replies": [
{
"id": 3,
"user": "testuser3",
"content": "ding",
"timestamp": "2021-02-09T15:29:38.230933+01:00"
}
],
"reply_id": null,
"timestamp": "2021-02-09T15:24:11.072502+01:00"
},
{
"id": 3,
"user": "testuser3",
"content": "ding",
"replies": [],
"reply_id": 2,
"timestamp": "2021-02-09T15:29:38.230933+01:00"
},
]
}
This is what I need.
"count": 5,
"next": null,
"previous": null,
"results": [
{
"id": 2,
"user": "testuser2",
"content": "comment test!",
"replies": [
{
"id": 3,
"user": "testuser3",
"content": "ding",
"timestamp": "2021-02-09T15:29:38.230933+01:00"
}
],
"reply_id": null,
"timestamp": "2021-02-09T15:24:11.072502+01:00"
},
]
}
UPDATE:
models.py
class Comment(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="post_comments")
reply = models.ForeignKey('Comment', null=True, related_name='replies', blank=True, on_delete=models.CASCADE)
content = models.TextField(max_length=1000)
timestamp = models.DateTimeField(auto_now_add=True)
views.py
class CommentPostAPIView(APIView):
permission_classes = (IsAuthenticated,)
# pagination_class = PageNumberPagination
def get(self, *args, **kwargs):
post = get_object_or_404(Post, slug=self.kwargs['slug'])
comments = Comment.objects.filter(post=post)
paginator = CustomPaginator()
response = paginator.generate_response(comments, CommentSerializer, self.request)
return response
Here I want to hide the replies from showing up along with the comments as replies are already nested along with respective comments. so comments with reply_id
are actually replies and one with null reply_id
's are comments. How can I prevent those from passing through.
Thank you
Upvotes: 1
Views: 384
Reputation: 1868
In your case you need to filter as @Chandan said before. So really you need to refactor your view with the reply_id
filter
permission_classes = (IsAuthenticated,)
# pagination_class = PageNumberPagination
def get(self, *args, **kwargs):
post = get_object_or_404(Post, slug=self.kwargs['slug'])
comments = Comment.objects.filter(post=post,reply_id__isnull=True)
paginator = CustomPaginator()
response = paginator.generate_response(comments, CommentSerializer, self.request)
return response
Upvotes: 0
Reputation: 11807
Your CommentSerializer
is correct problem is you are getting all comments and related replies from Comment
model in your view and passing to CommentSerializer
you need to filter and remove reply related to comment
Comment.objects.filter(reply_id__isnull=True)
Upvotes: 1
Reputation: 635
Serializers validation will work fine in this case.
If you need to add a condition to a specific field then create a method validate_fieldname
and if you want to add condition over a specific object then directly create a method as validate
.
You can read the documentation for more information - https://www.django-rest-framework.org/api-guide/serializers/#field-level-validation
Upvotes: 0
Reputation: 88569
set reply_id
field as write_only
class CommentSerializer(serializers.ModelSerializer):
content = serializers.CharField()
reply_id = serializers.PrimaryKeyRelatedField(
source='reply',
queryset=Comment.objects.all(),
required=False,
write_only=True
)
user = serializers.ReadOnlyField(source="user.username")
replies = CommentCreateSerializer(many=True, read_only=True)
class Meta:
model = Comment
fields = ['id', 'user', 'content', 'replies', 'reply_id', 'timestamp']
Upvotes: 0