Django-rest-framework 03(实例:用户注册、超级用户、认证、权限)

1、创建一个新应用

在这里插入图片描述
在setting里面配置这个应用
在这里插入图片描述

1.1、创建 User表

模型
在这里插入图片描述

from django.db import models


class User(models.Model):
    # unique=True 用户名不能重复
    u_name = models.CharField(max_length=32,unique=True)
    u_password = models.CharField(max_length=256)
    is_delete = models.BooleanField(default=False)
    is_super = models.BooleanField(default=False)


迁移
在这里插入图片描述

1.2、新建序列化器

新建序列化器:新建serializers.py,内容如下
在这里插入图片描述

from RESTuser.models import User
from rest_framework import serializers


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'id', 'u_name', 'u_password', 'is_super')


视图
在这里插入图片描述

from RESTuser.models import User
from RESTuser.serializers import UserSerializer
from rest_framework.generics import ListCreateAPIView


# ListCreateAPIView 获取列表数据,创建数据的类视图
# 获取全部用户
class UsersAPIView(ListCreateAPIView):
    serializer_class = UserSerializer
    queryset = User.objects.all()


# 获取单个用户
class UserAPIView(ListCreateAPIView):
    serializer_class = UserSerializer
    queryset = User.objects.all()

路由:在为应用RESTuser新建urls.py,内容如下

from RESTuser import views
from django.urls import path, re_path

urlpatterns = [
    path('users/', views.UsersAPIView.as_view()),
    re_path('users/(?P<pk>\d+)/', views.UserAPIView.as_view(),name='user-detail'),

]

在根路由注册:

在这里插入图片描述

1.3、运行测试

在这里插入图片描述
post请求
在这里插入图片描述

2、用户注册、登录

在setting里把超级管理员的用户名注册了,然后注册该用户名时就自动把它设为超级管理员

2.1、创建超级用户

setting.py
在这里插入图片描述
视图
在这里插入图片描述

from RESTuser.models import User
from RESTuser.serializers import UserSerializer
from rest_framework import status
from rest_framework.generics import ListCreateAPIView

# ListCreateAPIView 获取列表数据,创建数据的类视图
# 获取全部用户
from rest_framework.response import Response
from untitled.settings import SUPER_USER


class UsersAPIView(ListCreateAPIView):
    serializer_class = UserSerializer
    queryset = User.objects.all()

    # 重写父类的create()方法,创建超级用户
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        data = serializer.data
        u_name = data.get("u_name")

        # 如果该用户名在setting记录的超级用户中,就设置它为超级用户
        if u_name in SUPER_USER:
            u_id = data.get('id')
            user = User.objects.get(pk=u_id)
            user.is_super = True
            user.save()
            data.update({'is_super': 'True'})
        headers = self.get_success_headers(serializer.data)
        return Response(data, status=status.HTTP_201_CREATED, headers=headers)


# 获取单个用户
class UserAPIView(ListCreateAPIView):
    serializer_class = UserSerializer
    queryset = User.objects.all()

尝试创建超级用户
v

2.2、注册、登录

这里登录要用到redis缓存,redis的安装和使用参考下面网址

 https://blog.csdn.net/a__int__/article/details/103648033

 这个网址里的内容包含了使用redis出现问题的解决方案

在setting里面注册redis
在这里插入图片描述

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
        },
        'TIMEOUT': 60 * 60 * 2
    }
}

在serializers.py加入u_password(前面我创建序列化器的时候没有加)
在这里插入图片描述
新建constants.py并写入一下内容
在这里插入图片描述
在视图里面重写post方法

    # 这个post可以同时接收注册、和登录过来的数据,用action区分
    def post(self, request, *args, **kwargs):
        action = request.query_params.get('action')
        # 注册
        if action == HTTP_ACTION_REGISTER:
            return self.create(request, *args, **kwargs)
        # 登录
        elif action == HTTP_ACTION_LOGIN:
            u_name = request.data.get('u_name')
            u_password = request.data.get('u_password')
            try:
                user = User.objects.get(u_name=u_name)
                if user.u_password == u_password:
                    # 获取唯一标识码
                    token = uuid.uuid4().hex
                    # 登陆后会将标识码存入缓存
                    # cache.set(键, 值)
                    cache.set(token, user.id)
                    data = {
                        'msg': '登录成功',
                        'status': 200,
                        'token': token,
                    }
                    return Response(data)
                else:
                    # 认证失败
                    raise exceptions.AuthenticationFailed
            # 如果没有找到对应的用户,抛出异常
            except User.DoesNotExist:
                # 一旦执行了raise语句,raise后面的语句将不能执行
                raise exceptions.NotFound
        # 如果没有提供action,获取action没在我们规定的里面
        else:
            # ValidationError验证错误
            raise exceptions.ValidationError

测试:

注册用户

在这里插入图片描述
登录
在这里插入图片描述

2.3、用户认证

限制获取用户条件,使得登陆了才能通过GET获取用户列表,

创建一个认证类auth.py(从获取token,并验证数据库里是否有该用户)
在这里插入图片描述

from RESTuser.models import User
from django.core.cache import cache
from rest_framework.authentication import BaseAuthentication


class UserAuth(BaseAuthentication):
    # 重写认证方法
    def authenticate(self, request):
        # get请求获取数据是才验证权限,post等可能是注册或者登录,应该放开访问权限
        if request.method == 'GET':
            # request.query_params 这个获取的类型是 django里面的 QueryDict 类型
            token = request.query_params.get('token')
            try:
                # 获取缓存里的标识码token
                u_id = cache.get(token)
                # 到数据库里匹配id
                user = User.objects.get(pk=u_id)
                # 如果没报异常返回user, token
                return user, token
            except:
                return

视图
在这里插入图片描述

    # authentication_classes认证类
    authentication_classes = (UserAuth,)

    def get(self, request, *args, **kwargs):
        if isinstance(request.user, User):
            return self.list(request, *args, **kwargs)
        else:
            raise exceptions.NotAcceptable

3、用户权限

超级用户登录后才能获取用户列表思路:新建auth.py重写权限has_permission()方法,使其返回值为user的is_super,这样超级用户就直接返回True了

3.1、新建auth.py

在这里插入图片描述

from RESTuser.models import User
from rest_framework.permissions import BasePermission


# BasePermission是rest_framework里权限管理的基类
class IsSuperUser(BasePermission):
    def has_permission(self, request, view):
        # get请求获取数据是才验证权限,post等可能是注册或者登录,应该放开访问权限
        if request.method == 'GET':
            if isinstance(request.user, User):
                return request.user.is_super
            return False
        return True


3.2、视图

先注释掉之前写的get方法(因为这里面写的是所有用户登陆后都能访问)
在这里插入图片描述

    # permission_classes权限类,这里IsSuperUser返回user的is_super
    permission_classes = (IsSuperUser,)

3.3、测试

运行
在这里插入图片描述
先注册一个非超级用户

在这里插入图片描述
登录
在这里插入图片描述
填写token,获取用户列表
在这里插入图片描述
登录一个超级用户试试
在这里插入图片描述
填写token,获取用户列表
在这里插入图片描述
超级用户成功获取用户列表

代码总结

视图所有代码

import uuid

from RESTuser.auth import UserAuth
from RESTuser.constants import HTTP_ACTION_REGISTER, HTTP_ACTION_LOGIN
from RESTuser.models import User
from RESTuser.permissions import IsSuperUser
from RESTuser.serializers import UserSerializer
from django.core.cache import cache
from rest_framework import status, exceptions
from rest_framework.generics import ListCreateAPIView
from rest_framework.response import Response
from untitled.settings import SUPER_USER


# ListCreateAPIView 获取列表数据,创建数据的类视图
# 获取全部用户
class UsersAPIView(ListCreateAPIView):
    serializer_class = UserSerializer
    queryset = User.objects.all()
    # authentication_classes认证类,这里UserAuth认证该用户是否是数据库里的,如果是返回user, token
    authentication_classes = (UserAuth,)
    # permission_classes权限类,如果是get请求IsSuperUser返回user的is_super
    permission_classes = (IsSuperUser,)

    # def get(self, request, *args, **kwargs):
    #     # 判断如果用户在数据库里,返回用户列表
    #     if isinstance(request.user, User):
    #         return self.list(request, *args, **kwargs)
    #     else:
    #         raise exceptions.NotAcceptable

    # 这个post可以同时接收注册、和登录过来的数据,用action区分
    def post(self, request, *args, **kwargs):
        action = request.query_params.get('action')
        # 注册
        if action == HTTP_ACTION_REGISTER:
            return self.create(request, *args, **kwargs)
        # 登录
        elif action == HTTP_ACTION_LOGIN:
            u_name = request.data.get('u_name')
            u_password = request.data.get('u_password')
            try:
                user = User.objects.get(u_name=u_name)
                if user.u_password == u_password:
                    # 获取唯一标识码
                    token = uuid.uuid4().hex
                    # 登陆后会将标识码存入缓存
                    # cache.set(键, 值)
                    cache.set(token, user.id)
                    data = {
                        'msg': '登录成功',
                        'status': 200,
                        'token': token,
                    }
                    return Response(data)
                else:
                    # 认证失败
                    raise exceptions.AuthenticationFailed
            # 如果没有找到对应的用户,抛出异常
            except User.DoesNotExist:
                # 一旦执行了raise语句,raise后面的语句将不能执行
                raise exceptions.NotFound
        # 如果没有提供action,获取action没在我们规定的里面
        else:
            # ValidationError验证错误
            raise exceptions.ValidationError

    # 重写父类的create()方法,创建超级用户
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        data = serializer.data
        u_name = data.get("u_name")

        # 如果该用户名在setting记录的超级用户中,就设置它为超级用户
        if u_name in SUPER_USER:
            u_id = data.get('id')
            user = User.objects.get(pk=u_id)
            user.is_super = True
            user.save()
            data.update({'is_super': 'True'})
        headers = self.get_success_headers(serializer.data)
        return Response(data, status=status.HTTP_201_CREATED, headers=headers)


# 获取单个用户
class UserAPIView(ListCreateAPIView):
    serializer_class = UserSerializer
    queryset = User.objects.all()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值