Reputation: 817
Let us assume I have the following models
class Blog(models.Model):
user = models.ForeignKey(User, null=False, on_delete=models.CASCADE)
class Post(models.Model):
blog = models.ForeignKey(Blog, null=False, on_delete=models.CASCADE)
post = models.TextField()
The problem is that creating a Post will let me set the blog id to anything (that exists). That means that I am able to create a Post object that has a relation to a Blog
object that the user does not "own".
However, there are easy and documented ways to prevent the user from accessing objects via the GET
method, that are forbidden to them, by filtering the queryset and using check_object_permissions
. Example:
class PostViewSet(viewsets.ModelViewSet):
serializer = PostSerializer
def get_queryset(self):
return Post.objects.filter(blog__user=self.request.user)
def check_object_permissions(self, request, obj):
if obj.user != request.user:
raise exceptions.PermissionDenied()
super().check_object_permissions(request, obj)
How do I solve my above issue and prevent creating relations to forbidden objects the smartest/correct way in Django REST framework?
Upvotes: 0
Views: 268
Reputation: 47364
You can add blog validation to the serializer (check Field-level validation doc) and raise error if user dnt have permission to the selected blog:
class PostSerializer(serializers.ModelSerializer):
...
def validate_blog(self, value):
request = self.context['request']
if value.user != request.user:
raise serializers.ValidationError('Blog id doesn't exist')
return value
Upvotes: 1