django rest-framework知識點

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',
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章