首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Rest Framework序列化程序,禁止用户更改他人密码

Rest Framework序列化程序,禁止用户更改他人密码
EN

Stack Overflow用户
提问于 2018-08-31 06:36:21
回答 1查看 156关注 0票数 0

我正在创建一个简单的web应用程序,但我找不到任何方法来禁止其他用户更改您的密码。这是最小的代码:

代码语言:javascript
复制
# serializers.py
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    def create(self, validated_data):
        # have to use custom create method because default method calls `User.objects.create()` which doesn't take care of password hashing and other important stuff 
        return User.objects.create_user(**validated_data)

    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'password')
        read_only_fields = ('id', 'username')

        # password is set to write_only because I don't want to send it to anybode (even though it's just a hash)
        extra_kwargs = {'password': {'write_only': True}}

# views.py
from .serializers import UserSerializer
from rest_framework import generics
from django.contrib.auth.models import User

class UserDetails(generics.RetrieveUpdateAPIView):

    queryset = User.objects.all()
    serializer_class = UserSerializer

我可以通过使用APIView自己解决这个问题。

代码语言:javascript
复制
# views.py
from .serializers import UserSerializer
from rest_framework.views import APIView
from django.contrib.auth.models import User

class UserDetails(APIView):
    def put(self, request, format=None):

        serialized = UserSerializer(data=request.DATA)
        if not serialized.is_valid():
            return # probably HTTP 400 Error code
        if request.user.id != serialized.data['id']:
            # this if is what I'm trying to achieve
            return # probably HTTP 403 Error code
        user = User.objects.update(
            id=serialized.data['id'],
            email=serialized.data['email']
        )
        if 'password' in request.DATA:
            user.set_password(request.DATA['password'])
        return # probably HTTP 200 Error code

不幸的是,这会导致rest_framework.schemas.get_schema_view生成的方案是不完整的。我使用CoreAPI进行通信(它不能与方案中没有描述的东西通信),所以我不能这样做。我在官方文档中没有找到任何东西。这似乎是一个过于基本的问题,有一个我错过了的超级简单的解决方案。感谢你的任何想法或去哪里寻找。

PS:我使用的是django2.1和python3.6

编辑:osobacho的解决方案很干净,而且工作起来很有魅力。无论如何,我也需要允许修改(比如说对TODO- list )只允许todo列表的创建者。我以为密码问题的解决方案是适用的,但事实并非如此。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-31 07:44:53

您可以在请求中获取用户。这样,每个用户将只能更改自己的密码。

代码语言:javascript
复制
class UserDetails(generics.RetrieveUpdateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get_object(self):
        return self.request.user

对于您的第二个问题,请查看django_restframework http://www.django-rest-framework.org/api-guide/permissions/权限,下面是一个示例:

代码语言:javascript
复制
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""

def has_object_permission(self, request, view, obj):
    # Read permissions are allowed to any request,
    # so we'll always allow GET, HEAD or OPTIONS requests.
    if request.method in permissions.SAFE_METHODS:
        return True

    # Instance must have an attribute named `owner`.
    return obj.owner == request.user

然后,您需要添加到视图中:

代码语言:javascript
复制
 permission_classes = (IsOwnerOrReadOnly,)

希望能有所帮助

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52106232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档