Python 如何使用Django Rest框架根据不同的实例更改权限?
我使用的是Django rest框架,我的模型是这样的,每个动作可以有多个帖子Python 如何使用Django Rest框架根据不同的实例更改权限?,python,django,django-rest-framework,Python,Django,Django Rest Framework,我使用的是Django rest框架,我的模型是这样的,每个动作可以有多个帖子 class Act(models.Model): user = models.ForeignKey("common.MyUser", related_name="act_user") act_title = models.CharField(max_length=30) act_content = models.CharField(max_length=
class Act(models.Model):
user = models.ForeignKey("common.MyUser", related_name="act_user")
act_title = models.CharField(max_length=30)
act_content = models.CharField(max_length=1000)
act_type = models.IntField()
class Post(models.Model):
user = models.ForeignKey("common.MyUser", related_name="post_user")
act = models.ForeignKey("activities.Act", related_name="post_act")
post_title = models.CharField(max_length=30, blank=True)
post_content = models.CharField(max_length=140)
DRF中的my view.py:
class PostList(generics.ListCreateAPIView):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
queryset = Post.objects.all()
serializer_class = PostAllSerializer
def perform_create(self, serializer): #self is a instance of class or is a class here?
serializer.save(user=self.request.user)
这很好,但我现在想要的是,如果act_type=1表示这是一个私人行为,并且只有act作者才能在此行为下创建帖子。我想知道如何根据不同的act使用不同的权限类。可能看起来像:
class PostList(generics.ListCreateAPIView):
if self.act_type == 1:
permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsActCreatorOrReadOnly)
else
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
queryset = Post.objects.all()
serializer_class = PostAllSerializer
def perform_create(self, serializer): #self is a instance of class or is a class here?
serializer.save(user=self.request.user)
我还想知道如何编写这个permissions.py:
class IsActCreatorOrReadOnly(permissions.BasePermission):
"""
Custom permission to only allow owners of an object to edit it.
"""
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.act.user == request.user
我不知道obj在这里的真正含义,错误告诉我obj.act不存在
编辑
这是我的后序列化程序
class PostAllSerializer(serializers.ModelSerializer):
"""Posts api fields"""
post_user = UserSerializer(source="user", read_only=True)
post_author = serializers.ReadOnlyField(source='user.user_name')
class Meta:
model = Post
fields = ("id", "act", "post_author", "post_title", "post_content",)
我尝试过这个,但没有成功,即使我不是该法案的作者,我仍然可以创建帖子(但法案id是错误的):
对于使用不同的权限类,您可以在
PostList
视图中覆盖get\u permissions
方法:
def get_permissions(self):
if self.request.method == 'POST':
return (OnePermission(),)
elif # other condition if you have:
return (AnotherPermission(),)
return (YetAnotherPermission(),)
但是,在您的情况下,您不能使用对象级权限,因为您还没有对象实例。来自DRF(我的亮点):
REST框架权限还支持对象级权限。对象级权限用于确定是否应允许用户对特定对象进行操作,该对象通常是模型实例。
调用.get_Object()时,对象级权限由REST框架的通用视图运行
执行POST
请求时,您还没有任何对象,因此不会调用对象级权限
实现所需的一种方法是在PostList
视图的create
方法中选中它。类似于以下内容(假设代码):
祝你好运 你能发布你的
后序列化程序的代码吗?
?谢谢你,尤利安,我会编辑我的文章,但仍然没有工作。你到底编辑了什么?有什么变化吗?问题发生在哪里?我添加了PostSerializer.py并添加了我以前没有覆盖的“create”方法。您的是常见的.MyUser
类项目的AUTH\u USER\u模型
,还是您有一个与MyUser
有关系的标准用户模型?
def get_permissions(self):
if self.request.method == 'POST':
return (OnePermission(),)
elif # other condition if you have:
return (AnotherPermission(),)
return (YetAnotherPermission(),)
class PostList(generics.ListCreateAPIView):
...
def create(self, request):
act_id = request.data.get('act') # depending on your PostSerializer, the logic of getting act id can vary a little
act = Act.objects.get(pk=act_id) # assuming act always exists, otherwise account for in-existing act
if act.user != request.user:
return Response({details: "You shall not pass!!!", status=200) # change to a status and message you need here
# logic of Post creation here