外键项的 Django Rest Framework 权限
Django Rest Framework permission on a Foreign key item
我有两个模型有这样的关系:
class ManuscriptItem(models.Model):
"""Represents a single manuscript's content"""
author = models.ForeignKey('accounts_api.UserProfile', on_delete=models.CASCADE)
title = models.CharField(max_length=255)
content = models.CharField(max_length=99999999)
def __str__(self):
"""Django uses when it needs to convert the object to a string"""
return str(self.id)
class ManuscriptLibrary(models.Model):
"""Represents a single manuscript's library"""
manuscript = models.OneToOneField(ManuscriptItem, on_delete=models.CASCADE)
bookmarks = models.CharField(max_length=99999999)
history = models.CharField(max_length=99999999)
def __str__(self):
"""Django uses when it needs to convert the object to a string"""
return str(self.manuscript)
I want to only let a ManuscriptItem Author be able to assign a single
ManuscriptLibrary to that ManuscriptItem.
以下是我尝试过但没有成功的一些方法:
class PostOwnManuscriptLibrary(permissions.BasePermission):
"""Allow users to update their own manuscripts libraries."""
def has_object_permission(self, request, view, obj):
return obj.manuscript.author.id == request.user.id
Result: Everyone can write to any ManuscriptItem that they are not an
author of.
class PostOwnManuscriptLibrary(permissions.BasePermission):
def has_permission(self, request, view):
manuscript = ManuscriptLibrary.objects.filter(manuscript__author=request.user.id).exists()
return manuscript
Results: No one has any permissions, not even authors of their own
manuscript.
相关的 API 端点视图如下:
class ManuscriptViewSet(viewsets.ModelViewSet):
"""Handles creating, reading and updating items."""
authentication_classes = (TokenAuthentication,)
serializer_class = serializers.ManuscriptItemSerializer
permission_classes = (permissions.PostOwnManuscript, IsAuthenticated,)
def perform_create(self, serializer):
"""Sets the user profile to the logged in user."""
serializer.save(author=self.request.user)
def get_queryset(self):
"""
This view should return a list of all the manuscripts
for the currently authenticated user.
"""
user = self.request.user
return models.ManuscriptItem.objects.filter(author=user)
class ManuscriptLibraryViewSet(viewsets.ModelViewSet):
"""Handles creating, reading and updating manuscript library."""
authentication_classes = (TokenAuthentication,)
serializer_class = serializers.ManuscriptLibrarySerializer
permission_classes = (permissions.PostOwnManuscriptLibrary,)
def get_queryset(self):
"""
This view should return a list of all the manuscripts settings
where the manuscript author is the logged in user
"""
user = self.request.user
return models.ManuscriptLibrary.objects.filter(manuscript__author=user)
附加信息:
我已经覆盖了我的用户模型,因此在我的 settings.py 中包括:
# Takes the model and assigns it!
AUTH_USER_MODEL = 'profiles_api.UserProfile'
在我的用户个人资料中 API
class UserProfile(AbstractBaseUser, PermissionsMixin):
"""Represents a "user profile" inside our system."""
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserProfileManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
def get_full_name(self):
"""Used to get a users full name."""
return self.name
def get_short_name(self):
"""Used to get a users short name."""
return self.name
def __str__(self):
"""Django uses this when it needs to convert the object to a string"""
return self.email
修复:
Made adjustments as per BearBrown's suggestions, needed to query the
right model:
class PostOwnManuscriptLibrary(permissions.BasePermission):
"""Allow users to update their own manuscripts libraries."""
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.manuscript.author == request.user
def has_permission(self, request, view):
if request.method == 'POST':
manuscript = request.data.get('manuscript')
print(manuscript)
instance = ManuscriptItem.objects.get(pk=manuscript)
return instance.author == request.user
return True
我想你可以试试这个:
class PostOwnManuscriptLibrary(permissions.BasePermission):
"""Allow users to update their own manuscripts libraries."""
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.manuscript.author == request.user
def has_permission(self, request, view):
if request.method == 'POST':
manuscript = request.data.get('manuscript')
instance = ManuscriptLibrary.objects.get(pk=manuscript)
return instance.author == request.user
return True
完成 'POST' 后,从请求中获取 manuscript
数据并使用 request.author
使 ManuscriptLibrary.author
无效
查看
class ManuscriptLibraryViewSet(viewsets.ModelViewSet):
"""Handles creating, reading and updating manuscript library."""
authentication_classes = (TokenAuthentication,)
serializer_class = serializers.ManuscriptLibrarySerializer
queryset = models.ManuscriptLibrary.objects.all()
permission_classes = (permissions.PostOwnManuscriptLibrary,)
我有两个模型有这样的关系:
class ManuscriptItem(models.Model):
"""Represents a single manuscript's content"""
author = models.ForeignKey('accounts_api.UserProfile', on_delete=models.CASCADE)
title = models.CharField(max_length=255)
content = models.CharField(max_length=99999999)
def __str__(self):
"""Django uses when it needs to convert the object to a string"""
return str(self.id)
class ManuscriptLibrary(models.Model):
"""Represents a single manuscript's library"""
manuscript = models.OneToOneField(ManuscriptItem, on_delete=models.CASCADE)
bookmarks = models.CharField(max_length=99999999)
history = models.CharField(max_length=99999999)
def __str__(self):
"""Django uses when it needs to convert the object to a string"""
return str(self.manuscript)
I want to only let a ManuscriptItem Author be able to assign a single ManuscriptLibrary to that ManuscriptItem.
以下是我尝试过但没有成功的一些方法:
class PostOwnManuscriptLibrary(permissions.BasePermission):
"""Allow users to update their own manuscripts libraries."""
def has_object_permission(self, request, view, obj):
return obj.manuscript.author.id == request.user.id
Result: Everyone can write to any ManuscriptItem that they are not an author of.
class PostOwnManuscriptLibrary(permissions.BasePermission):
def has_permission(self, request, view):
manuscript = ManuscriptLibrary.objects.filter(manuscript__author=request.user.id).exists()
return manuscript
Results: No one has any permissions, not even authors of their own manuscript.
相关的 API 端点视图如下:
class ManuscriptViewSet(viewsets.ModelViewSet):
"""Handles creating, reading and updating items."""
authentication_classes = (TokenAuthentication,)
serializer_class = serializers.ManuscriptItemSerializer
permission_classes = (permissions.PostOwnManuscript, IsAuthenticated,)
def perform_create(self, serializer):
"""Sets the user profile to the logged in user."""
serializer.save(author=self.request.user)
def get_queryset(self):
"""
This view should return a list of all the manuscripts
for the currently authenticated user.
"""
user = self.request.user
return models.ManuscriptItem.objects.filter(author=user)
class ManuscriptLibraryViewSet(viewsets.ModelViewSet):
"""Handles creating, reading and updating manuscript library."""
authentication_classes = (TokenAuthentication,)
serializer_class = serializers.ManuscriptLibrarySerializer
permission_classes = (permissions.PostOwnManuscriptLibrary,)
def get_queryset(self):
"""
This view should return a list of all the manuscripts settings
where the manuscript author is the logged in user
"""
user = self.request.user
return models.ManuscriptLibrary.objects.filter(manuscript__author=user)
附加信息:
我已经覆盖了我的用户模型,因此在我的 settings.py 中包括:
# Takes the model and assigns it!
AUTH_USER_MODEL = 'profiles_api.UserProfile'
在我的用户个人资料中 API
class UserProfile(AbstractBaseUser, PermissionsMixin):
"""Represents a "user profile" inside our system."""
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserProfileManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
def get_full_name(self):
"""Used to get a users full name."""
return self.name
def get_short_name(self):
"""Used to get a users short name."""
return self.name
def __str__(self):
"""Django uses this when it needs to convert the object to a string"""
return self.email
修复:
Made adjustments as per BearBrown's suggestions, needed to query the right model:
class PostOwnManuscriptLibrary(permissions.BasePermission):
"""Allow users to update their own manuscripts libraries."""
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.manuscript.author == request.user
def has_permission(self, request, view):
if request.method == 'POST':
manuscript = request.data.get('manuscript')
print(manuscript)
instance = ManuscriptItem.objects.get(pk=manuscript)
return instance.author == request.user
return True
我想你可以试试这个:
class PostOwnManuscriptLibrary(permissions.BasePermission):
"""Allow users to update their own manuscripts libraries."""
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.manuscript.author == request.user
def has_permission(self, request, view):
if request.method == 'POST':
manuscript = request.data.get('manuscript')
instance = ManuscriptLibrary.objects.get(pk=manuscript)
return instance.author == request.user
return True
完成 'POST' 后,从请求中获取 manuscript
数据并使用 request.author
ManuscriptLibrary.author
无效
查看
class ManuscriptLibraryViewSet(viewsets.ModelViewSet):
"""Handles creating, reading and updating manuscript library."""
authentication_classes = (TokenAuthentication,)
serializer_class = serializers.ManuscriptLibrarySerializer
queryset = models.ManuscriptLibrary.objects.all()
permission_classes = (permissions.PostOwnManuscriptLibrary,)