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()
尝试创建超级用户
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()