用户模块
登陆注册1:Django2.0
[ 1:N ]
- user/url.py
1 from django.urls import path 2 from user.views0 import UserTypeView, SingleUserView 3 4 app_name = 'user' 5 urlpatterns = [ 6 # 注意:::此处必须变量名定义名为pk,否则系统识别不到 7 path('singleuser/<int:pk>', SingleUserView.as_view(), name='user-detail'), 8 path('usertype/', UserTypeView.as_view(), name='usertype'), 9 ]
- user/models.py
1 from django.db import models 2 3 # 1 4 class UserType(models.Model): 5 name = models.CharField(max_length=20, unique=True) 6 add_time = models.DateTimeField(auto_now=True) 7 8 class Meta: 9 db_table = 'user_type' 11 def __str__(self): 12 return self.name 13 14 # n 15 class User(models.Model): 16 username = models.CharField(max_length=20, unique=True) 17 password = models.CharField(max_length=128) 18 phone = models.CharField(max_length=11) 19 add_time = models.DateTimeField(auto_now=True) 20 # related_name='users'的作用是usertype.user_set.all ===> usertype.users.all 21 usertype = models.ForeignKey(to=UserType, on_delete=models.CASCADE, related_name='users', null=True) 22 23 class Meta: 24 db_table = 'user' 26 def __str__(self): 27 return self.username
- user/serializers.py
1 from django.contrib.auth.hashers import make_password 2 from rest_framework import serializers 3 from user.models import User, UserType
1 class UserSerializerSimple(serializers.ModelSerializer): 2 repassword = serializers.CharField(max_length=128, write_only=True) 3 4 class Meta: 5 model = User # 序列化的模型以及字段 6 fields = ['id', 'username', 'password', 'phone', 'repassword'] 7 # 重写validate类方法。实现密码和确认密码验证 8 def validate(self, attrs): 9 if attrs['password'] != attrs['repassword']: 10 raise serializers.ValidationError('两次密码不相等') 11 return attrs 12 # 重写create类方法。实现密码加密功能 13 def create(self, validated_data): 14 username = validated_data['username'] 15 password = validated_data['password'] 16 phone = validated_data['phone'] 17 password = make_password(password) # 密码加密 18 user = User.objects.create(username=username, password=password, phone=phone) 19 return user
1 # 也可以继承自:serializers.HyperlinkedModelSerializer实现超链接 2 class UserTypeSerializer(serializers.ModelSerializer): 3 """ 4 # 1。 5 # StringRelatedField表示定义序列化的关系模型[两张表的关系定义]。many=True 表示有多个值时需要声明为True。 6 # users命名要和模型中外键字段定义的related_name='users'中定义的名字一致,且需要添加到下方Meta的fields中 7 # 最后返回到前端的是对应的从表对象的名称 8 users = serializers.StringRelatedField(many=True) 9 # 2。 10 # 也可以使用PrimaryKeyRelatedField。 11 # 最后返回到前端的是对应的从表对象的主键 12 users = serializers.PrimaryKeyRelatedField(many=True, read_only=True) 13 """ 14 # 3。 15 # 也可以使用 HyperlinkedRelatedField超链接格式,view_name='user:user-detail'需要定义用户的超链接(url) 16 # 最后返回到前端的是对应的从表对象的链接格式(url) 17 users = serializers.HyperlinkedRelatedField(read_only=True, many=True, view_name='user:user-detail') 18 19 class Meta: 20 model = UserType 21 fields = '__all__' 22 23 class SingleUserSerializer(serializers.ModelSerializer): 24 class Meta: 25 model = User 26 fields = ['id', 'username', 'password', 'phone', 'usertype'] 27
1 # 也可以继承自:serializers.HyperlinkedModelSerializer实现超链接 2 class SingleUserSerializer(serializers.ModelSerializer): 3 class Meta: 4 model = User 5 fields = ['id', 'username', 'password', 'phone', 'usertype']
- user/views.py
1 from django.http import JsonResponse 2 from rest_framework.views import APIView 3 from user.models import User, UserType 4 from user.serializers import UserTypeSerializer, SingleUserSerializer, 5 UserSerializerSimple 6 7 class UserViewsSimple(APIView): 8 def get(self, request): 9 pass 10 def post(self, request): 11 user_serializer = UserSerializerSimple(data=request.data) 12 if user_serializer.is_valid(): 13 user_serializer.save() 14 return JsonResponse({'status': 200, 'user': user_serializer.data})
1 class UserTypeView(APIView): 2 def get(self, request): 3 usertypes = UserType.objects.all() 4 """ 5 将从数据库中查询到的数据在UserTypeSerializer中进行序列化。 6 序列化的是多个值时,需要添加many=True自动将usertypes转为列表类型 7 """ 8 serializer = UserTypeSerializer(usertypes, many=True, context={'request': request}) 9 data = { 10 'status': 200, 11 'types': serializer.data 12 } 13 return JsonResponse(data)
1 class SingleUserView(APIView): # 获取单个 2 def get(self, request, pk): 3 user = User.objects.get(pk=pk) 4 serializer = SingleUserSerializer(user, context={'request': request}) 5 data = { 6 'status': 200, 7 'types': serializer.data 8 } 9 return JsonResponse(data)
-
用户注册
-
数据开始:模型,数据库创建用户
-
用户身份:管理员、普通、删除用户
-
-
注册实现
-
添加了超级管理员生成
-
-
-
用户登陆
-
验证用户名密码;生成用户令牌
-
出现登陆和注册的post冲突。添加action
-
path/?action=login
-
path/?action=register
-
-
异常捕获尽量精确
-
-
用户认证
-
BaseAuthentication
-
authenticate:认证成功会返回一个元组
-
第一个元素是(user)用户对象
-
第二个元素是(token或auth)令牌
-
-
-
-
用户权限
-
BasePermission
-
has_permission:是否具有权限
-
true拥有权限
-
false没有权限
-
-
-
-
用户认证和权限
-
直接配置在视图函数上就ok了
-
认证权限2:Django1.11
- settings.py
1 # 特定超级用户列表 2 SUPER_USERS = ('GYP', 'LS','ROOT') 3 4 # 缓存书库库 5 CACHES = { 6 'default': { 7 'BACKEND': 'django_redis.cache.RedisCache', 8 'LOCATION': 'redis://127.0.0.1:6379/1', 9 'OPTIONS': { 10 'CLIENT_CLASS': 'django_redis.client.DefaultClient', 11 }, 12 'TIMEOUT': 60 * 60 *2 13 } 14 }
- urls.py
1 # 主url分发 2 from django.conf.urls import url, include 3 from django.contrib import admin 4 5 urlpatterns = [ 6 url(r'^admin/', admin.site.urls), 7 url(r'uauth/',include('UserAuthAndPermission.urls')) 8 ] 10 # ————————————————————————————------------------------------------------------------# 12 # 子url配置 13 from django.conf.urls import url 14 from UserAuthAndPermission import views 15 16 # HyperlinkedModelSerializer超链接的序列化需要为超链接配置好一个返回的url的路径url 17 urlpatterns = [ 18 # 用户注册登陆路由 19 url(r'^users/$', views.UsersAPIView.as_view()), 20 # name='usermodel-detail'。系统默认的报错配置名字 21 url(r'^users/(?P<pk>d+)/$', views.UserAPIView.as_view(), name='usermodel-detail'), 22 ]
- UserAuthAndPermission/models.py
1 from django.db import models 2 3 # 用户模型 4 class UserModel(models.Model): 5 u_name = models.CharField(max_length=32,unique=True) 6 u_password = models.CharField(max_length=256) 7 is_delete = models.BooleanField(default=False) 8 is_super = models.BooleanField(default=False)
- UserAuthAndPermission/serializers.py
1 from rest_framework import serializers 2 from UserAuthAndPermission.models import UserModel 3 4 # serializers万能键导入不可用,需要手动导入;HyperlinkedModelSerializer带超链接url的序列化 5 class UserSerializer(serializers.HyperlinkedModelSerializer): 6 class Meta: 7 model = UserModel 8 fields = ('url', 'id', 'u_name', 'u_password', 'is_super')
- UserAuthAndPermission/constants.py
1 # 自定义常量类 2 HTTP_ACTION_LOGIN = 'login' 4 HTTP_ACTION_REGISTER = 'register'
- UserAuthAndPermission/auth.py
1 from django.core.cache import cache 2 from rest_framework.authentication import BaseAuthentication 3 from UserAuthAndPermission.models import UserModel 4 5 6 # 认证 7 # 继承自系统类BaseAuthentication。认证用户是否登陆 8 class UserAuth(BaseAuthentication): 9 # 实现父类中的抽象方法authenticate,增登陆认证功能。认证成功可返回元组:用户和令牌 10 def authenticate(self, request): 11 if request.method == "GET": 12 token = request.query_params.get('token') 13 try: 14 u_id = cache.get(token) 15 user = UserModel.objects.get(pk=u_id) 16 return user, token 17 except: 18 return None
- UserAuthAndPermission/permissions.py
1 from rest_framework.permissions import BasePermission 2 from UserAuthAndPermission.models import UserModel 3 4 # 权限。只有登陆认证过,并且是超级管理员用户才可以查询所有 5 # 继承自BasePermission。进行权限限制判断是否是超级管理员用户 6 class IsSuperUser(BasePermission): 7 # 重写has_permission系统方法。 8 def has_permission(self, request, view): 9 if request.method == "GET": # 又有get请求才会去判断权限 10 # 判断是否是模型的实例(判断某个对象是否是某个类的实例) 11 if isinstance(request.user, UserModel): 12 return request.user.is_super 13 return False 14 return True
- UserAuthAndPermission/views.py
1 import uuid 2 from django.core.cache import cache 3 from rest_framework import status, exceptions 4 from rest_framework.generics import ListCreateAPIView 5 from rest_framework.response import Response 6 from DjangoREST.settings import SUPER_USERS 7 from UserAuthAndPermission.auth import UserAuth 8 from UserAuthAndPermission.constants import HTTP_ACTION_REGISTER, HTTP_ACTION_LOGIN 9 from UserAuthAndPermission.models import UserModel 10 from UserAuthAndPermission.permissions import IsSuperUser 11 from UserAuthAndPermission.serializers import UserSerializer 12 13 14 # 实现所有查询get和创建post功能的类视图继承方式 15 class UsersAPIView(ListCreateAPIView): 16 # 模型序列化,系统默认变量名serializer_class 17 serializer_class = UserSerializer 18 # 从模型中查询获取数据。queryset也是系统默认变量名 19 queryset = UserModel.objects.all() 20 # 认证类。验证用户登陆认证。只有登陆的用户才可以查询 21 authentication_classes = (UserAuth,) 22 # 权限类。验证用户类型权限。只有超级管理员才可以查询 23 permission_classes = (IsSuperUser,) 24 25 # # get请求。只有是登陆认证认证过的 才可以查询 26 # def get(self, request, *args, **kwargs): 27 # # 判断是否是模型的实例(判断某个对象是否是某个类的实例) 28 # if isinstance(request.user, UserModel): 29 # return self.list(request, *args, **kwargs) 30 # else: 31 # raise exceptions.NotAuthenticated 32 33 34 # 重写ListCreateAPIView已有的post请求。实现登陆、注册。出现登陆注册公用post问题 35 # 解决:添加action动作(path/?action=login 或者 path/?action=register 36 def post(self, request, *args, **kwargs): 37 # 获取查询参数,相当于django中的额GET方法。 38 action = request.query_params.get('action') 39 # 判断是什么动作 40 if action == HTTP_ACTION_REGISTER: # 注册 41 return self.create(request, *args, **kwargs) 42 elif action == HTTP_ACTION_LOGIN: # 登陆 43 u_name = request.data.get('u_name') 44 u_password = request.data.get('u_password') 45 46 try: 47 user = UserModel.objects.get(u_name=u_name) 48 if user.u_password == u_password: 49 # 登陆成功,给用户一个token令牌存到缓存中 50 token = uuid.uuid4().hex 51 cache.set(token, user.id) 52 data = { 53 'msg': 'login success', 54 'status': 200, 55 'token': token 56 } 57 return Response(data) 58 else: 59 # 系统系统的状态信息常量类exceptions 60 raise exceptions.AuthenticationFailed 61 except UserModel.DoesNotExist: # 异常捕获要精确 62 raise exceptions.NotFound 63 else: 64 raise exceptions.ValidationError 65 66 # 重写系统create()方法。指定超级用户的列表在settings.py文件中指定 67 # 超级用户问题实现:只要是在即有特定列表中的用户注册时就自动设为超级用户。 68 def create(self, request, *args, **kwargs): 69 # 源码 70 serializer = self.get_serializer(data=request.data) 71 serializer.is_valid(raise_exception=True) 72 self.perform_create(serializer) 73 74 data = serializer.data 75 u_name = data.get('u_name') 76 # 判断是否是已有列表中的超级用户 77 if u_name in SUPER_USERS: 78 u_id = data.get('id') 79 user = UserModel.objects.get(pk=u_id) 80 user.is_super = True 81 user.save() 82 # 更新返回信息 83 data.update({'is_super': True}) 84 headers = self.get_success_headers(serializer.data) 85 return Response(data, status=status.HTTP_201_CREATED, headers=headers) 86 87 88 # 实现单个查询get和创建post功能的类视图继承方式 89 class UserAPIView(ListCreateAPIView): 90 # 模型序列化,系统默认变量名serializer_class 91 serializer_class = UserSerializer 92 # 从模型中查询获取数据。queryset也是系统默认变量名 93 queryset = UserModel.objects.all()