drf配置大全

1、配置响应格式

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类
        'rest_framework.renderers.JSONRenderer',  # json渲染器
         'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器
    )
}

2、自定义响应类

from rest_framework.response import Response


class APIResponse(Response):
    def __init__(self, code=100,msg=None,data=None, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None,**kwargs):
        dic = {'code':code,'msg':msg}
        if data:
            dic['data'] = data
        if kwargs:
            dic.update(kwargs)
        super(APIResponse, self).__init__(data=dic,status=status,
                    template_name=template_name,headers=headers,exception=exception,
                                          content_type=content_type)

3、自动生成路由

from rest_framework.routers import SimpleRouter

router = SimpleRouter()
router.register('publish',views.PublishView)

urlpatterns = [
    path('admin/', admin.site.urls),
    # 添加路由的方法一:
    path('api/',include(router.urls))
]

# 添加路由的方法二:
urlpatterns += router.urls


# 只有继承了ViewSetMixin+9个视图子类才能自动生成路由

4、可以使用action配置自定义路由

class PublishView(ModelViewSet):
    queryset = models.Publish.objects.all()
    serializer_class = serializer.PublishSerializer

    # detail为False的路由
    # http://127.0.0.1:8000/publish/send_sms/
    @action(methods=['GET'], detail=False)
    def send_sms(self, request):
        return APIResponse(msg='发送成功')

    # detail为True的路由
    # http://127.0.0.1:8000/publish/10/send_sms/
    @action(methods=['GET'], detail=True)
    def send_email(self, request, *args, **kwargs):
        print(args)  # ()
        print(kwargs)  # {'pk': '10'}
        return APIResponse(msg='发送成功')

5、登录认证类

5.1、认证类编写

app01/auth

from app01 import models
from rest_framework.exceptions import AuthenticationFailed
from rest_framework.authentication import BaseAuthentication


# 继承BaseAuthentication类
class LoginAuth(BaseAuthentication):
    # 函数名必须为authenticate
    def authenticate(self, request):
        token = request.GET.get('token')
        user_token = models.UserToken.objects.filter(token=token).first()
        if user_token:
            # 必须返回两个值,第二个值不重要,可以为空
            return user_token.user, ''
        else:
            raise AuthenticationFailed('没有登录')


5.2、全局使用

settings.py

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.auth.LoginAuth",]
}

5.3、局部禁用

在要禁用登录认证的类中写以下代码:
authentication_classes = []

6、权限类

6.1、权限类编写

class PermissionAuth(BasePermission):
    message = '你没有权限'
    def has_permission(self, request, view):

        if request.user.user_type == 1:
            return True
        else:
            self.message = '你是%s,你没有权限' % request.user.get_user_type_display()
            return False

6.2、全局使用

REST_FRAMEWORK={
    'DEFAULT_PERMISSION_CLASSES':['app01.auth.PermissionAuth'],
}

6.3、局部禁用

在要禁用的视图类中写以下代码:
permission_classes = []

7、频率类

7.1、频率类编写

class ThrottleAuth(SimpleRateThrottle):
    scope = 'ip_th'
    def get_cache_key(self, request, view):
        # 返回用户ip,按照ip对频率进行限制
        return self.get_ident(request)

7.2、全局使用

REST_FRAMEWORK={
    'DEFAULT_THROTTLE_CLASSES':['app01.auth.ThrottleAuth'],
    'DEFAULT_THROTTLE_RATES':{
        'ip_th':'5/m',
    },
}

7.3、局部禁用

在要禁用的类下面写以下代码:
throttle_classes = []

8、过滤类

8.1、内置过滤类的使用

8.1.1、在视图类中配置过滤类

# 只有继承了GenericApiView的类才能使用内置过滤类
from rest_framework.filters import SearchFilter


class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

    # 配置过滤类
    filter_backends = [SearchFilter,]
    # 配置过滤字段
    search_fields = ['name','price']

8.1.2、使用过滤

# 支持模糊查询

http://127.0.0.1:8000/book/?search=三英战吕布
        
http://127.0.0.1:8000/book/?search=582.02

8.1.3、全局使用

REST_FRAMEWORK={
    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.searchFilter',]
}

注意:需要在要使用过滤的视图中配置过滤字段

8.2、第三方过滤类的使用

8.2.1、第三方过滤类的配置(推荐使用)

# 1、安装
pip3 install django-filter

# 2、在settings.py中配置
INSTALLED_APPS = [
    'django_filters'
]

8.2.2、在视图类中配置过滤类

from django_filters.rest_framework import DjangoFilterBackend


class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

    # 使用第三方过滤类
    filter_backends = [DjangoFilterBackend, ]
    filter_fields = ['name', 'price']

8.2.3、使用过滤

# 不支持模糊查询

http://127.0.0.1:8000/book/?name=双节棍
        
http://127.0.0.1:8000/book/?name=双节棍&price=582.02

8.2.4、全局使用

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend',]
}

注意:需要在要使用过滤的视图中配置过滤字段

8.3、自定义过滤类

1 写一个过滤类
from rest_framework.filters import BaseFilterBackend
class Myfilter(BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        name = request.GET.get('name')
        queryset = queryset.filter(name__contains=name)
        return queryset
2 在视图类中配置
	## 自己定义的
    filter_backends = [Myfilter, ]

9、排序

9.1、配置排序类

from rest_framework.filters import OrderingFilter


class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

    # 使用排序类
    filter_backends = [OrderingFilter, ]
    ordering_fields = ['price','name']

9.2、使用排序类

http://127.0.0.1:8000/book/?ordering=price # 升序
http://127.0.0.1:8000/book/?ordering=-price # 降序
        
http://127.0.0.1:8000/book/?ordering=-price,-name # 按多个关键字排序

10、自动生成接口文档

# 1、安装
pip3 install coreapi

# 2、使用步骤
	1 在路由中
    from rest_framework.documentation import include_docs_urls
    urlpatterns = [
    path('doc/', include_docs_urls(title='路飞项目接口文档')),
	]
   2 在配置文件中
	REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
	}
  3 在视图类中方法上加注释即可
  4 如果是ModelViewSet
    	"""
       list:
       返回图书列表数据,通过Ordering字段排序

       retrieve:
       返回图书详情数据

       latest:
       返回最新的图书数据

       read:
       查询单个图书接口
       """
  5 字段描述,写在models的help_text上

11、全局异常封装

查看无车承运人流程

12、分页器

12.1、普通分页PageNumberPagination

# 1、自定义一个类,继承PageNumberPagination
from rest_framework.pagination import PageNumberPagination


class MyPagination(PageNumberPagination):
    # 重写四个类属性
    page_size = 3 # 默认每页显示的条数
    page_query_param = 'page' # 查询条件叫page  ?page=3
    page_size_query_param = 'size' # 每页显示的条数的查询条件    ?page=3&size=10
    max_page_size = 5    # 每页显示的最大条数
    
    
# 2、在视图类中配置
from app01.page import MyPagination

class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

    # 使用分页
    pagination_class = MyPagination # 不能是列表

12.2、偏移分页LimitOffsetPagination

# 1、自定义一个类,继承LimitOffsetPagination
from rest_framework.pagination import LimitOffsetPagination


class MyLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 3
    limit_query_param = 'limit'
    offset_query_param = 'offset'  # ?offset=2&limit=5   从第二条开始展示五条
    max_limit = 5

    
# 2、在视图类中配置
from app01.page import MyPagination

class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

    # 使用分页
    pagination_class = MyLimitOffsetPagination # 不能是列表

12.3、游标分页

# 1、自定义一个类,继承CursorPagination
from rest_framework.pagination import CursorPagination


# 这种分页方式很特殊,只能选择上一页和下一页,不能指定跳转到某一页
# 优点是速度快,适合大数据量和app的分页
class MyCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'  # 查询参数
    page_size = 3  # 每页显示多少条
    ordering = 'nid'  # 按照什么字段排序
    
    
# 2、在视图类中配置
class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

    pagination_class = MyCursorPagination # 不能是列表

12.4、三种分页方式对比

1、普通分页和游标分页可以从中间位置获取任意一页,游标分页只能获取上一页和下一页
2、普通分页和游标分页在获取某一页的时候,都需要从开始过滤到要取的页面数的数据
3、游标分页先对数据进行排序,内部维护了一个游标,游标只能选择往前走或者往后走,在取某一页的时候,不需要过滤之前的数据

13、rbac

# python用来做公司内部项目居多,人事系统,进销存,报销审批,自动化运维
	-公司内部项目对执行效率要求不高(人少)
  -对开发效率要求高(越快开发出越好,成本越低越好)
  -知乎,豆瓣用python写的---》随着用户量增大---》切换语言
# 对外的权限比较简单:普通注册用户,VIP用户,超级VIP  --》优酷,网易云音乐,百度网盘
# 公司内部系统:通常使用RBAC的权限控制
		-公司内有部门(开发部,运维部,市场部,总裁办,人力资源部门)
  	-权限和角色(部门)绑定   
    -举个例子:发工资权限,招人权限,开发代码权限---》招人权限,发工资权限给人力资源--》开发代码权限给开发部门



# RBAC  是基于角色的访问控制(Role-Based Access Control )在 RBAC  中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。

# 权限赋予给角色(部门),而把角色(部门)又赋予用户

# 针对于公司内部项目,后台管理居多(运营在使用),使用rbac居多
# django-vue-admin:后端用drf,前端用vue,权限管理的 脚手架---》前后端分离
# django的admin---》混合的后台管理用的多---》基于django的admin二次开发
# simpleui:对django admin的美化

# django的admin自带rbac权限管理(表设计完成权限管理)---》6张表
	-用户表
  -角色表(组表,部门表)
  -权限表
  ----------
  -角色和权限多对多中间表
  -用户和角色多对多中间表
  -----django-admin中多了一张表-----
  用户对权限多对多中间表
  
  
  
### 基于django的admin做二次开发,开发出公司内部的管理系统
	-纯基于原生
  	
  -使用第三方美化:xadmin(早就不维护了,弃坑了),simpleui(国内的,主流),国外也有很多
  
  
  
  
# 在关系型数据库的关系中:只有三种---》本质只有一种:外键关系
  	-一对多
    -多对多
    -一对一
    
    
# 前后端分离,验证码如何实现?写验证码接口
  

14、jwt认证

14.1、jwt介绍

# cookie,session,token的区别?
https://www.cnblogs.com/liuqingzheng/articles/8990027.html
# 认证:session机制:需要在后端存储数据---》之前使用的django-session
# 如果登录用户很多,需要在后端存很多数据,频繁查询数据库,导致效率低---》能不能想一种方案,不在服务端存数据---》客户端存数据(数据安全)---》token认证机制


# Json web token (JWT),token是一种认证机制,用在web开发方向,叫jwt

# JWT的构成---》三段式---》每一段都使用base64编码
	-典型的jwt串样子,通过. 分隔成三段:
 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
	-第一段:头:声明类型,这里是jwt,声明加密的算法,公司信息等等。。。 ---》 目前作用不大
  -第二段:荷载(payload):有效信息
    	-用户名,用户id,登陆时间,token失效时间。。。。
  -第三段:签名(signature):通过  头+荷载 使用某种加密方式加密后得到的
    

    
# base64编码和解码---》只是编码和解码,不能叫加密
import base64

# 编码
# s = b'''{"name":"lqz","age":19}'''
# res = base64.b64encode(s)
# print(res)  # eyJuYW1lIjoibHF6IiwiYWdlIjoxOX0=

# 解码
# s=b'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9'
# res=base64.b64decode(s)
# print(res)



## jwt的签发和认证---》保证安全
# 签发---》登陆过程---》如果没有第三方模块帮助我们做,我们就自己做
"""
1)用基本信息公司信息存储json字典,采用base64算法得到 头字符串
2)用关键信息存储json字典,采用base64算法得到 荷载字符串,过期时间,用户id,用户名
3)用头、体加密字符串通过加密算法+秘钥加密得到 签名字符串
拼接成token返回给前台
"""


# 认证---》访问需要登陆的接口
"""
1)将token按 . 拆分为三段字符串,第一段 头加密字符串 一般不需要做任何处理
2)第二段 体加密字符串,要反解出用户主键,通过主键从User表中就能得到登录用户,过期时间是安全信息,确保token没过期
3)再用 第一段 + 第二段 + 加密方式和秘钥得到一个加密串,与第三段 签名字符串 进行比较,通过后才能代表第二段校验得到的user对象就是合法的登录用户
"""

# 大部分的web框架都会有第三方模块支持----》如果没有需要自己写
django中有一个django-rest-framework-jwt,咱们讲的:
# https://github.com/jpadilla/django-rest-framework-jwt
django中有一个,django-rest-framework-simplejwt,咱们不讲,公司可能会用:
# https://github.com/jazzband/djangorestframework-simplejwt

# 区别
# https://blog.csdn.net/lady_killer9/article/details/103075076
	

14.2、jwt安装

pip3 install djangorestframework-jwt

14.3、签发token

# 1、配置路由
from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    path('login/',obtain_jwt_token)
]

# 2、使用postman模拟发送POST请求,jwt会基于auth_user表签发token
http://127.0.0.1:8001/login/
        
# 3、得到token
{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6InRpYW55YW5sb25nIiwiZXhwIjoxNjUyMTQ5MzczLCJlbWFpbCI6InRpYW55YW5sb25nMjAwMEAxNjguY29tIn0.EsiJc8pwkrNeRjSOmjVhNJxJ-llf5avNdQY2ZnHoIQ0"
}

14.4、认证token

# 1、在视图类中配置
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import IsAuthenticated


class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer
    # jwt认证类
    authentication_classes = [JSONWebTokenAuthentication, ]
    # 加一个权限类才可以使用
    permission_classes = [IsAuthenticated, ]
    
# 2、使用
http://127.0.0.1:8000/book/
访问这个url时,需要在请求头中添加  Authorization : jwt token字符串    这一组键值对

14.5、jwt定制前端返回格式

# 1、自定义函数==》函数返回什么,前端就能看到什么格式
utils.py
def jwt_response_payload_handler(token, user=None, request=None):
    return {
        'code': 100,
        'msg': "登陆成功",
        'token': token,
        'username': user.username
    }

# 2、在配置文件中配置
JWT_AUTH = {
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.utils.jwt_response_payload_handler',
}

14.6、自定义表签发token

14.6.1、把认证逻辑写在视图类中

# 如果项目中的User表使用auth_user表,使用快速签发token即可
# 如果自定义User表,签发token,需要手动签发---》自己写

from app01.response import APIResponse
from rest_framework.viewsets import ViewSetMixin
from rest_framework.decorators import action
from app01 import models
from rest_framework_jwt.settings import api_settings
from rest_framework.generics import GenericAPIView
from app01 import serializer

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


class UserInfoView(ViewSetMixin, GenericAPIView):
    queryset = models.UserInfo.objects.all()
    serializer_class = serializer.UserInfoSerializer

    @action(methods=['POST'], detail=False)
    def login(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = models.UserInfo.objects.filter(username=username, password=password).first()
        if user:
            # 用户存在,签发token
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            return APIResponse(msg='登陆成功', payload=payload, token=token)
        else:
            return APIResponse(code=101, msg='用户名或密码错误')

14.6.2把认证逻辑写在序列化类中

# 序列化类
class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = ['username','password']

    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')

        user = models.UserInfo.objects.filter(username=username,password=password).first()
        if user:
            # 表示用户名和密码正确,签发token
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            self.context['token'] = token
            self.context['payload'] = payload
            return attrs
        else:
            raise ValidationError('用户名或密码错误')
            
            
# 视图类
class UserInfoView(ViewSetMixin, GenericAPIView):
    queryset = models.UserInfo.objects.all()
    serializer_class = serializer.UserInfoSerializer

    @action(methods=['POST'], detail=False)
    def login(self, request):
        ser = serializer.UserInfoSerializer(data=request.data)
        if ser.is_valid():
            # context是视图类和序列化类沟通的桥梁
            token = ser.context.get('token')
            payload = ser.context.get('payload')
            return APIResponse(msg='登录成功', payload=payload, token=token)
        else:
            return APIResponse(code=101, msg=ser.errors)

14.7、自定义认证token

from rest_framework_jwt.authentication import JSONWebTokenAuthentication
import jwt
from rest_framework_jwt.settings import api_settings
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
# jwt自定义登录认证类
class JWTAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 先获取到token
        jwt_value = request.META.get('HTTP_TOKEN')
        if jwt_value is None:
            raise AuthenticationFailed('token为空')

        try:
            payload = jwt_decode_handler(jwt_value)
        except jwt.ExpiredSignature:
            msg = '签名已过期'
            raise AuthenticationFailed(msg)
        except jwt.DecodeError:
            msg = '签名被篡改'
            raise AuthenticationFailed(msg)
        except jwt.InvalidTokenError:
            raise AuthenticationFailed('未知错误')

        user = models.UserInfo.objects.filter(pk=payload['user_id'])

        return (user, jwt_value)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Django中使用DRFDjango Rest Framework)需要进行以下配置: 1. 安装DRF 可以通过pip安装DRF,命令如下: ``` pip install djangorestframework ``` 2. 在INSTALLED_APPS中添加'rest_framework' 在settings.py中的INSTALLED_APPS列表中添加'rest_framework',如下所示: ``` INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'myapp', ] ``` 3. 配置REST_FRAMEWORK设置 在settings.py中添加REST_FRAMEWORK设置,以配置DRF的一些选项,如下所示: ``` REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ], } ``` 以上设置包括了DRF中的默认身份验证类、默认权限类和默认渲染器类。可以根据需要进行修改。 4. 创建序列化器 在myapp中创建一个serializers.py文件,定义一个序列化器类,如下所示: ``` from rest_framework import serializers from myapp.models import MyModel class MyModelSerializer(serializers.ModelSerializer): class Meta: model = MyModel fields = '__all__' ``` 5. 创建视图 在myapp中创建一个views.py文件,定义一个视图类,如下所示: ``` from rest_framework import generics from myapp.models import MyModel from myapp.serializers import MyModelSerializer class MyModelList(generics.ListCreateAPIView): queryset = MyModel.objects.all() serializer_class = MyModelSerializer ``` 以上视图类继承了DRF提供的generics.ListCreateAPIView类,用于实现查询和创建操作。可以根据需要进行修改。 6. 创建URL 在myapp中的urls.py文件中定义一个URL,将视图类和URL绑定在一起,如下所示: ``` from django.urls import path from myapp.views import MyModelList urlpatterns = [ path('mymodel/', MyModelList.as_view(), name='mymodel-list'), ] ``` 以上是Django使用DRF的基本配置。可以根据项目需求进行调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值