我的应用程序需要 DRF 中的权限。
输入:
未经身份验证的用户只能阅读出版物和图像
经过身份验证的用户可以创建出版物并添加图像
授权用户可以编辑和删除他们作为作者的出版物和图像
管理员用户可以执行所有操作,但编辑内容
型号:
class Publication(models.Model):
pub_text = models.TextField(null=True, blank=True)
pub_date = models.DateTimeField(auto_now_add=True)
pub_author = models.ForeignKey(User, on_delete=models.CASCADE)
class Image(models.Model):
image = models.ImageField(upload_to='images', null=True)
image_to_pub = models.ForeignKey(Publication, on_delete=models.CASCADE, null=True, related_name='images')
浏览次数:
class PublicationViewSet(viewsets.ModelViewSet):
queryset = Publication.objects.all()
serializer_class = PublicationSerializer
permission_classes = [PublicPermission]
class ImageViewSet(viewsets.ModelViewSet):
queryset = Image.objects.all()
serializer_class = ImageSerializer
permission_classes = [ImagePermission]
权限:
class ImagePermission(BasePermission):
edit_methods = ['PUT', 'PATCH']
def has_permission(self, request, view):
if request.method in SAFE_METHODS:
return True
if request.user.is_authenticated:
return True
def has_object_permission(self, request, view, obj):
if request.user.is_superuser:
return True
if request.method in SAFE_METHODS:
return True
if request.user.id == Publication.objects.get(id=obj.image_to_pub_id).pub_author_id:
return True
if request.user.is_staff and request.method not in self.edit_methods:
return True
return False
class ImageAuthorPermission(BasePermission):
def has_object_permission(self, request, view, obj):
if request.user.id == Publication.objects.get(id=obj.image_to_pub_id).pub_author_id:
return True
return False
现在它的工作原理就像我上面描述的那样。但我不确定这是否是好的做法。
我的意思是班级
如果我从
如果我从
我确信有更好的方法来自定义此权限。不是有吗
我还尝试检查当前用户是否对与用户作者的出版物相关的图像具有对象权限。这是可行的,但是是否有标准实践如何检查相关对象的权限?我尝试删除支票
if request.user.id == Publication.objects.get(id=obj.image_to_pub_id).pub_author_id:
从 中取出
我看到了这部分并实现了它。
首先,SAFE_METHOD请求必须是只读的,并且只能对经过身份验证的用户进行创建等操作。
对于这部分,使用 DRF Permission 默认提供的 IsAuthenticatedOrReadOnly 类。
rest_framework.permission
class IsAuthenticatedOrReadOnly(BasePermission):
"""
The request is authenticated as a user, or is a read-only request.
"""
def has_permission(self, request, view):
return bool(
request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated
)
实现第3、4条,只有所有者可以修改和删除,管理员只能修改(“PUT”,“PATCH”)。
首先,我创建了 AdminObjectPermission 类来解决数字 4。
class AdminObjectPermission(BasePermission):
def has_object_permission(self, request, view, obj):
if bool(request.user and request.user.is_staff) and request.method in ["PUT", "PATCH"]:
return True
从上面的代码可以看出,Client是admin用户,请求中使用的方法必须是“PATCH”或“PUT”
对于第 3 个,您可以将 request.user 与对象的用户连接起来。
from rest_framework.permissions import IsAuthenticatedOrReadOnly, BasePermission
class AdminObjectPermission(BasePermission):
def has_object_permission(self, request, view, obj):
if bool(request.user and request.user.is_staff) and request.method in ["PUT", "PATCH"]:
return True
class PublicPermission(IsAuthenticatedOrReadOnly, AdminObjectPermission):
def has_object_permission(self, request, view, obj):
if super().has_object_permission(request, view, obj):
return True
if request.user.id == obj.pub_author.id:
return True
return False
class ImagePermission(IsAuthenticatedOrReadOnly, AdminObjectPermission):
def has_object_permission(self, request, view, obj):
if super().has_object_permission(request, view, obj):
return True
if request.user.id == obj.image_to_pub.pub_author.id:
return True
return False
对于 Publication 对象,它通过 pub_author 字段与 User 关联。
if request.user.id == obj.pub_author.id
通过 pub_author 在连接的 Publication 对象上比较图像对象。
if request.user.id == obj.image_to_pub.pub_author.id