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