基本的Django REST框架 - 只写资源

时间:2014-12-21 18:37:35

标签: python django python-2.7 django-rest-framework

我正在尝试创建一个简单的服务,允许匿名用户提交他们的姓名和电子邮件。我希望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

我应该用什么以及在哪里制作它以便用户可以提交他们的姓名和电子邮件,但只有管理员可以阅读,更新,删除?谢谢你的帮助。

1 个答案:

答案 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

您还需要控制视图级别上使用的序列化程序。这需要使用permissionsoverridden 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在视图上手动覆盖它。