我正在尝试创建一个简单的服务,允许匿名用户提交他们的姓名和电子邮件。我希望AllowAny添加他们的信息,IsAuthenticated在其他一切。我无法获得这种粒度。
models.py
from django.db import models
class Invitee(models.Model):
name = models.CharField(max_length=255)
email = models.EmailField(max_length=70,blank=True)
modified = models.DateTimeField(auto_now=True)
serializers.py
class InviteeSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Invitee
fields = ('name', 'email')
def create(self, validated_data):
return Invitee(**validated_data)
views.py
class InviteeViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Invitee.objects.all()
serializer_class = InviteeSerializer
我应该用什么以及在哪里制作它以便用户可以提交他们的姓名和电子邮件,但只有管理员可以阅读,更新,删除?谢谢你的帮助。
答案 0 :(得分:5)
最简单,最安全的方法是使用多个序列化程序,这是您需要的每个用户类之一。您还需要使用自定义权限来强制认证用户和匿名用户之间的读/写区别。
class InviteeSerializer(serializers.HyperlinkedModelSerializer):
def create(self, validated_data):
return Invitee(**validated_data)
class LimitedInviteeSerializer(InviteeSerializer):
class Meta:
model = Invitee
fields = ('name', 'email', ) # a limited subset of the fields
class FullInviteeSerializer(InviteeSerializer):
class Meta:
model = Invitee
fields = ('name', 'email', "modified", ) # all of the fields
虽然现在看起来只需要读/写,但如果您需要完整的读/写/删除权限,我建议reading this Stack Overflow question。
您还需要控制视图级别上使用的序列化程序。这需要使用permissions和overridden view methods的组合来完成。
class InviteeViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Invitee.objects.all()
serializer_class = LimitedInviteeSerializer
def get_serializer_class(self):
if self.request.user.is_active:
return FullInviteeSerializer
return super(InviteeViewSet, self).get_serializer_class()
在视图上,您需要覆盖get_serializer_class
以确定应该使用哪个序列化程序,具体取决于用户是否处于活动状态。永远不应将匿名用户标记为活动用户,因此这是在排除已停用帐户时检查的最佳方式。
您还需要创建一个与内置IsAuthenticatedOrReadOnly
permission相反的自定义权限类。您正在寻找经过身份验证的用户来执行所有操作,而匿名用户只能是只写用户。我已将此类IsAuthenticatedOrWriteOnly
称为与其他权限类匹配。
class IsAuthenticatedOrWriteOnly(BasePermission):
"""
The request is authenticated as a user, or is a write-only request.
"""
def has_permission(self, request, view):
WRITE_METHODS = ["POST", ]
return (
request.method in WRITE_METHODS or
request.user and
request.user.is_authenticated()
)
您只需将现有的权限类列表添加,或使用permission_classes
在视图上手动覆盖它。