Django DRF实现用户数据权限控制
在 Django DRF 中使用 ModelViewSet 时,若需实现用户仅能查看和操作自己的数据详情,同时允许所有认证用户访问列表,需结合权限类和动态权限分配。以下是具体步骤:
1. 自定义对象权限类
创建一个 IsOwner 权限类,检查请求用户是否为对象所有者:
python
from rest_framework import permissionsclass IsOwner(permissions.BasePermission):def has_object_permission(self, request, view, obj):# 确保只有所有者可以执行对象级别的操作(如详情、更新、删除)return obj.owner == request.user
### 2. 在 ModelViewSet 中动态分配权限
覆盖 get_permissions 方法,根据不同操作应用不同权限:
python
from rest_framework import viewsets, permissions
from .models import MyModel
from .serializers import MyModelSerializerclass MyModelViewSet(viewsets.ModelViewSet):queryset = MyModel.objects.all()serializer_class = MyModelSerializerdef get_permissions(self):# 针对列表和创建操作,仅需用户认证if self.action in ['list', 'create']:permission_classes = [permissions.IsAuthenticated]else:# 针对详情、更新、删除,需认证且是所有者permission_classes = [permissions.IsAuthenticated, IsOwner]return [permission() for permission in permission_classes]
3. 过滤列表数据(推荐)
通常更安全的做法是过滤列表仅显示用户自己的数据,避免信息泄露:
python
def get_queryset(self):# 确保用户只能看到自己的数据return MyModel.objects.filter(owner=self.request.user)
此时权限类只需 IsAuthenticated,因为列表和详情已通过过滤限制数据访问:
python
class MyModelViewSet(viewsets.ModelViewSet):permission_classes = [permissions.IsAuthenticated]def get_queryset(self):return MyModel.objects.filter(owner=self.request.user)
总结方案
动态权限分配:通过 get_permissions 区分列表和详情操作的权限,允许列表访问但限制详情。
数据过滤:使用 get_queryset 过滤数据,确保用户只能访问自己的条目,这是更安全的做法。
选择方案取决于需求:
允许列表显示所有数据:动态权限 + 不过滤 queryset,但需注意数据暴露。
仅显示用户数据:过滤 queryset + 简单权限,更推荐此方式以确保数据安全。