django rest-framework知识点

本文深入探讨Django框架下用户权限管理,包括自定义用户模型、REST框架权限控制、序列化器高级用法及密码管理。同时,解决中文搜索问题,提供详实代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 在建立model时对django自带的user做补充

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
class ANUser(AbstractBaseUser, PermissionsMixin, JsonableObject):
    pass

2. 在viewset中设置用户权限访问

from rest_framework import permissions, viewsets
class CompanyViewSet(views.ModelViewSet):
    authentication_classes = [OAuth2Authentication, SessionAuthentication]
    permission_classes = [permissions.IsAuthenticated]
    queryset = Company.objects.all()
    serializer_class = CompanySerializer

permission_classes就是rest framework中关于viewset的权限控制。

IsAuthenticated是用户身份验证,需要用户登录才可以拥有访问权限

IsAuthenticatedOrReadOnly用户登录可以执行所有的操作,但是用户如果没有登录的话就只有只读的权限

AllowAny是所有用户不管有没有登录都可以访问

IsAdminUser是只有管理员才有权限访问

3. 在viewset中可以使用装饰器action写新的方法,而且这个方法还会自行生成路由,不需要你重新注册,可以说是非常方便了。

from django.contrib.auth.models import User
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from myapp.serializers import UserSerializer, PasswordSerializer

class UserViewSet(viewsets.ModelViewSet):
    """
    A viewset that provides the standard actions
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @action(detail=True, methods=['post'])
    def set_password(self, request, pk=None):
        user = self.get_object()
        serializer = PasswordSerializer(data=request.data)
        if serializer.is_valid():
            user.set_password(serializer.data['password'])
            user.save()
            return Response({'status': 'password set'})
        else:
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

    @action(detail=False)
    def recent_users(self, request):
        recent_users = User.objects.all().order_by('-last_login')

        page = self.paginate_queryset(recent_users)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(recent_users, many=True)
        return Response(serializer.data)

 以上是官方文档给出的例子,其中detail=True or detail=False指的是该额外的操作针对的是一个对象还是集合,也就是对应的路由/user/recent_users还是/user/{pk}/recent_users。methods是确定该操作的请求方法。其他的全凭自己发挥。

4. 有些create or update方法需要在序列化器中实现:

ForeignKey

class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer()

    class Meta:
        model = User
        fields = ('username', 'email', 'profile')

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        user = User.objects.create(**validated_data)
        Profile.objects.create(user=user, **profile_data)
        return user

或者是:ManyToManyField

class User(models.Model):
    profile = models.ManyToManyField(Profile)


class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer()

    class Meta:
        model = User
        fields = ('username', 'email', 'profile')

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        user = User.objects.create(**validated_data)
        for profile in profile_data:
            p = Profile.objects.create(**profile_data)
            user.profile.add(p)
        return user

5. 在序列化器中序列化的时候可以自定义,例如:

class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer()
    username = serializers.SerializerMethodField()
    def get_username(self, obj):
        return obj.username + obj.name
    class Meta:
        model = User
        fields = ('username', 'email', 'profile')

6. 在django中创建的用户,用户的密码一般使用哈希加密之后存放在数据库中,在用户修改密码的时候

class ProfileUpdateViewSet(generics.UpdateAPIView):
    authentication_classes = [OAuth2Authentication, SessionAuthentication]
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = PasswordSerializer

    def update(self, request, pk=None, *args, **kwargs):
        user = self.request.user
        serializer = PasswordSerializer(data=request.data)
        if serializer.is_valid():
            if serializer.data['password'] == serializer.data['confirm']:
                if check_password(serializer.data['old'], user.password):
                    user.set_password(serializer.data['password'])
                    user.save()
                    return Response('password set')
                else:
                    return Response('The old password error', status=status.HTTP_400_BAD_REQUEST)
            else:
                return Response('The two passwords you entered did not match', status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

使用check_password()来判段密码是否正确,用user.set_password来给用户设置密码,用make_password()将普通的字符串密码转化为哈希格式,可以直接存入数据库。

7. 其中有的表支持中文搜索,而有的表不支持,提示OperationalError: (1271, "Illegal mix of collations for operation 'like'")的错误

找到django包下面的\site-packages\django\db\backends\mysql\base.py文件并编辑,将operators下的icontains对应的值修改为'LIKE BINARY %s'

operators = {
        'exact': '= %s',
        'iexact': 'LIKE %s',
        'contains': 'LIKE BINARY %s',
        'icontains': 'LIKE BINARY %s',
        'gt': '> %s',
        'gte': '>= %s',
        'lt': '< %s',
        'lte': '<= %s',
        'startswith': 'LIKE BINARY %s',
        'endswith': 'LIKE BINARY %s',
        'istartswith': 'LIKE %s',
        'iendswith': 'LIKE %s',
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值