用户模块

登陆注册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. 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'
  10. def __str__(self):
  11. return self.name
  12.  
  13. 14 # n
  14. class User(models.Model):
  15. username = models.CharField(max_length=20, unique=True)
  16. password = models.CharField(max_length=128)
  17. phone = models.CharField(max_length=11)
  18. add_time = models.DateTimeField(auto_now=True)
  19. # related_name='users'的作用是usertype.user_set.all ===> usertype.users.all
  20. usertype = models.ForeignKey(to=UserType, on_delete=models.CASCADE, related_name='users', null=True)
  21.  
  22. class Meta:
  23. db_table = 'user'
  24. def __str__(self):
  25. 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. 3 """
  4. 4 # 1。
  5. 5 # StringRelatedField表示定义序列化的关系模型[两张表的关系定义]。many=True 表示有多个值时需要声明为True。
  6. 6 # users命名要和模型中外键字段定义的related_name='users'中定义的名字一致,且需要添加到下方Meta的fields中
  7. 7 # 最后返回到前端的是对应的从表对象的名称
  8. users = serializers.StringRelatedField(many=True)
  9. 9 # 2。
  10. 10 # 也可以使用PrimaryKeyRelatedField。
  11. 11 # 最后返回到前端的是对应的从表对象的主键
  12. users = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
  13. 13 """
  14. 14 # 3。
  15. 15 # 也可以使用 HyperlinkedRelatedField超链接格式,view_name='user:user-detail'需要定义用户的超链接(url)
  16. 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. 1 # 特定超级用户列表
  2. SUPER_USERS = ('GYP', 'LS','ROOT')
  3.  
  4. 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. 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. ]
  9. # ————————————————————————————------------------------------------------------------#
  10. 12 # 子url配置
  11. from django.conf.urls import url
  12. from UserAuthAndPermission import views
  13.  
  14. # HyperlinkedModelSerializer超链接的序列化需要为超链接配置好一个返回的url的路径url
  15. urlpatterns = [
  16. # 用户注册登陆路由
  17. url(r'^users/$', views.UsersAPIView.as_view()),
  18. # name='usermodel-detail'。系统默认的报错配置名字
  19. url(r'^users/(?P<pk>\d+)/$', views.UserAPIView.as_view(), name='usermodel-detail'),
  20. ]
  • 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'
  3. 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 # 认证
  6. # 继承自系统类BaseAuthentication。认证用户是否登陆
  7. class UserAuth(BaseAuthentication):
  8. # 实现父类中的抽象方法authenticate,增登陆认证功能。认证成功可返回元组:用户和令牌
  9. def authenticate(self, request):
  10. if request.method == "GET":
  11. token = request.query_params.get('token')
  12. try:
  13. u_id = cache.get(token)
  14. user = UserModel.objects.get(pk=u_id)
  15. return user, token
  16. except:
  17. return None
  • UserAuthAndPermission/permissions.py
  1. from rest_framework.permissions import BasePermission
  2. from UserAuthAndPermission.models import UserModel
  3.  
  4. 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. # 实现所有查询get和创建post功能的类视图继承方式
  14. class UsersAPIView(ListCreateAPIView):
  15. # 模型序列化,系统默认变量名serializer_class
  16. serializer_class = UserSerializer
  17. # 从模型中查询获取数据。queryset也是系统默认变量名
  18. queryset = UserModel.objects.all()
  19. # 认证类。验证用户登陆认证。只有登陆的用户才可以查询
  20. authentication_classes = (UserAuth,)
  21. # 权限类。验证用户类型权限。只有超级管理员才可以查询
  22. permission_classes = (IsSuperUser,)
  23.  
  24. # # get请求。只有是登陆认证认证过的 才可以查询
  25. # def get(self, request, *args, **kwargs):
  26. # # 判断是否是模型的实例(判断某个对象是否是某个类的实例)
  27. # if isinstance(request.user, UserModel):
  28. # return self.list(request, *args, **kwargs)
  29. # else:
  30. # raise exceptions.NotAuthenticated
  31.  
  32. # 重写ListCreateAPIView已有的post请求。实现登陆、注册。出现登陆注册公用post问题
  33. # 解决:添加action动作(path/?action=login 或者 path/?action=register
  34. def post(self, request, *args, **kwargs):
  35. # 获取查询参数,相当于django中的额GET方法。
  36. action = request.query_params.get('action')
  37. # 判断是什么动作
  38. if action == HTTP_ACTION_REGISTER: # 注册
  39. return self.create(request, *args, **kwargs)
  40. elif action == HTTP_ACTION_LOGIN: # 登陆
  41. u_name = request.data.get('u_name')
  42. u_password = request.data.get('u_password')
  43.  
  44. try:
  45. user = UserModel.objects.get(u_name=u_name)
  46. if user.u_password == u_password:
  47. # 登陆成功,给用户一个token令牌存到缓存中
  48. token = uuid.uuid4().hex
  49. cache.set(token, user.id)
  50. data = {
  51. 'msg': 'login success',
  52. 'status': 200,
  53. 'token': token
  54. }
  55. return Response(data)
  56. else:
  57. # 系统系统的状态信息常量类exceptions
  58. raise exceptions.AuthenticationFailed
  59. except UserModel.DoesNotExist: # 异常捕获要精确
  60. raise exceptions.NotFound
  61. else:
  62. raise exceptions.ValidationError
  63.  
  64. # 重写系统create()方法。指定超级用户的列表在settings.py文件中指定
  65. # 超级用户问题实现:只要是在即有特定列表中的用户注册时就自动设为超级用户。
  66. def create(self, request, *args, **kwargs):
  67. # 源码
  68. serializer = self.get_serializer(data=request.data)
  69. serializer.is_valid(raise_exception=True)
  70. self.perform_create(serializer)
  71.  
  72. data = serializer.data
  73. u_name = data.get('u_name')
  74. # 判断是否是已有列表中的超级用户
  75. if u_name in SUPER_USERS:
  76. u_id = data.get('id')
  77. user = UserModel.objects.get(pk=u_id)
  78. user.is_super = True
  79. user.save()
  80. # 更新返回信息
  81. data.update({'is_super': True})
  82. headers = self.get_success_headers(serializer.data)
  83. return Response(data, status=status.HTTP_201_CREATED, headers=headers)
  84.  
  85. # 实现单个查询get和创建post功能的类视图继承方式
  86. class UserAPIView(ListCreateAPIView):
  87. # 模型序列化,系统默认变量名serializer_class
  88. serializer_class = UserSerializer
  89. # 从模型中查询获取数据。queryset也是系统默认变量名
  90. queryset = UserModel.objects.all()

中级大招

django 之(三) --- 认证|权限的更多相关文章

  1. Django REST framework认证权限和限制和频率

    认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...

  2. Django REST Framework 认证 - 权限 - 限制

    一. 认证 (你是谁?) REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案. 自定义Token认证 第一步 : 建表>>>> 定义一个 ...

  3. Django REST framework认证权限和限制 源码分析

    1.首先 我们进入这个initial()里面看下他内部是怎么实现的. 2.我们进入里面看到他实现了3个方法,一个认证,权限频率 3.我们首先看下认证组件发生了什么 权限: 啥都没返回,self.per ...

  4. django-rest-framework 基础三 认证、权限和频率

    django-rest-framework 基础三 认证.权限和频率 目录 django-rest-framework 基础三 认证.权限和频率 1. 认证 1.1 登录接口 1.2 认证 2. 权限 ...

  5. Django Rest Framework(认证、权限、限制访问频率)

    阅读原文Django Rest Framework(认证.权限.限制访问频率) django_rest_framework doc django_redis cache doc

  6. Django集成OpenLDAP认证

    本文详细介绍了django-auth-ldap的使用方法,参数含义,并提供了示例代码 版本说明 Django==2.2 django-auth-ldap==1.7.0 集成过程 Django集成LDA ...

  7. Django Rest framework 之 权限

    django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) django res ...

  8. python 全栈开发,Day79(Django的用户认证组件,分页器)

    一.Django的用户认证组件 用户认证 auth模块 在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中: 如果用户存在于数据库中,然后再验证用户 ...

  9. [django]drf知识点梳理-权限

    用户 - 权限 - 资源 (拥有) (绑定) django权限机制能够约束用户行为,控制页面的显示内容,也能使API更加安全和灵活:用好权限机制,能让系统更加强大和健壮 django权限控制 Djan ...

随机推荐

  1. IP分组

    IP 分组为了更准确地讨论 I n t e r n e t协议处理,我们必须定义一些名词.图 显示了在不同的I n t e r n e t层之间传递数据时用来描述数据的名词.我们把传输协议交给 I P ...

  2. Redis键值设计(转载)

    参考资料:https://blog.csdn.net/iloveyin/article/details/7105181 丰富的数据结构使得redis的设计非常的有趣.不像关系型数据库那样,DEV和DB ...

  3. Python sleep()函数用法:线程睡眠

    如果需要让当前正在执行的线程暂停一段时间,并进入阻塞状态,则可以通过调用 time 模块的 sleep(secs) 函数来实现.该函数可指定一个 secs 参数,用于指定线程阻塞多少秒. 当前线程调用 ...

  4. PHP mysqli_error() 函数

    返回最近调用函数的最后一个错误描述: <?php  // 假定数据库用户名:root,密码:123456,数据库:RUNOOB  $con=mysqli_connect("localh ...

  5. js中错误处理机制

    1.基本知识 1. 错误对象 Error,SyntaxError,RangeError, ReferenceError,TypeError,URIError 上面的都是构造函数: new 命令可以生成 ...

  6. 彻底搞懂prototype和__proto__

    prototype是函数特有的属性,是Function的静态属性:__proto__是对象特有的属性. 因为函数本身是一种对象,所以函数既有prototype属性也有__proto__属性. 当函数使 ...

  7. java线程安全与不安全的理解

    存在成员变量(全局变量)的类用于多线程时是不安全的,不安全体现在这个成员变量可能发生非原子性的操作,而变量定义在方法内也就是局部变量是线程安全的. 想想在使用struts1时,不推荐创建成员变量,因为 ...

  8. mac brew 使用教程

    brew services list                  #查看系统通过 brew 安装的服务 brew services cleanup               #清除已卸载无用的 ...

  9. C语言学习笔记6-数组

    本系列文章由jadeshu编写,转载请注明出处.http://blog.csdn.net/jadeshu/article/details/50752170 作者:jadeshu   邮箱: jades ...

  10. MySQL 取分组后每组的最新记录

    修改<常用SQL之日期格式化和查询重复数据>中表test1的创建时间,修改后的测试数据如下: 以姓名分组后提取每组最新创建的记录: SELECT a.* FROM test1 AS a, ...