So I building a blog rest_api which has models
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
text = models.TextField()
approved = models.BooleanField(default=False)
...
class Comment(models.Model):
reply_to = models.ForeignKey(Post, default=None, on_delete=models.CASCADE)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
text = models.TextField()
approved = models.BooleanField(default=False)
As you see both posts and comments have to be approved, posts have to be approved by admins and comments have to be approved by post owners. Also, a user who creates a post has the ability to delete, put and patch fields expect the approved field which can only be patched a superuser.
Same with the comments they can be created by anyone but can only be approved by post owners and superuser. So far here are my serialisers.
class CommentSerializers(ModelSerializer):
class Meta:
model = Comment
fields = ['id','text', 'author']
read_only_fields = ['author']
class PostSerializers(ModelSerializer):
comments = CommentSerializers(source='comment_set', many=True, read_only=True)
class Meta:
model = Post
fields = [ 'id', 'text', 'author', 'approved', 'comments',]
read_only_fields = ['author', 'approved',]
def create(self,validated_data):
user = self.context['request'].user
instance=Post.objects.create(author=user ,**validated_data)
return instance
And here are my views and permissions
Views:
class PostListView(ListCreateAPIView):
permission_classes = [IsAuthenticated|ReadOnly]
serializer_class = PostSerializers
def perform_create(self, serializer):
serializer.save()
def get_queryset(self):
return Post.objects.filter(approved=True ).order_by('-published_date')
class PostDetailView(RetrieveUpdateDestroyAPIView):
permission_classes = [IsAuthenticated|ReadOnly]
serializer_class = PostSerializers
lookup_field = "id"
def get_queryset(self):
return Post.objects.filter(approved=True)
class CommentListView(ListCreateAPIView):
serializer_class = CommentSerializers
permission_classes = [IsAuthenticated|ReadOnly]
def perform_create(self, serializer):
post_id = self.kwargs['post_id']
post=Post.objects.get(id = post_id)
user = self.request.user
serializer.save(reply_to = post, author=user )
def get_queryset(self):
post_id = self.kwargs['post_id']
return Comment.objects.filter(reply_to=post_id ,approved=True)
class CommentDetailView(RetrieveUpdateDestroyAPIView):
permission_classes = [IsAuthenticated|ReadOnly]
serializer_class = CommentSerializers
lookup_field = "id"
def get_queryset(self):
return Comment.objects.filter(approved=True)
Permissions:
class ReadOnly(BasePermission):
def has_permission(self, request, view):
return request.method in SAFE_METHODS
class IsSuperUser(BasePermission):
def has_permission(self, request, view):
return request.user and request.user.is_superuser
class IsOwner(BasePermission):
def has_object_permission(self, request, view, obj):
if request.user:
if request.user.is_superuser:
return True
else:
return obj.author == request.user
else:
return False
class IsOwnerOfPost(BasePermission):
def has_object_permission(self,request, view, obj):
if request.user:
if request.user.is_superuser:
return True
else:
return obj.post.author == request.user
else:
return False