1.DRF框架的8个核心功能
 
  1.认证(用户登录校验用户名密码或者token是否合法)
  2.权限(根据不同的用户角色,可以操作不同的表)
  3.限流(限制接口访问速度)
  4.序列化(返回json)
  5.分页
  6.版本(接口版本号,用 v1/v2/v3)
  # api.example.com/v1/login # 只有用户名密码登录
  # api.example.com/v2/login # 手机号,微信 登录
7.过滤(username=zhangsan)
  8.排序(ordering=-id)
2.相关包
  1. '''1.序列化相关'''
  2. serializer
    ModelSerializer
  3. '''2.DRF视图函数继承'''
  4. APIView
  5. ModelViewSet
1.1 安装DjangoRestFramework
  1. pip install djangorestframework==3.11.1
  2. pip install django-filter==2.3.0 # 过滤器
  3. pip install markdown # Markdown support for the browsable API.
1.2 在syl/settings.py中注册
  1. INSTALLED_APPS = [
  2. 'django_filters',
  3. 'rest_framework',
  4. ]
1.3 syl/settings.py配置DRF: 全局配置
  1. REST_FRAMEWORK = {
  2.  
  3. # 文档报错: AttributeError: ‘AutoSchema’ object has no attribute ‘get_link’
  4. # 用下面的设置可以解决
  5.  
  6. 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema',
  7. # 默认设置是:
  8. # 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.openapi.AutoSchema',
  9.  
  10. # 异常处理器
  11. # 'EXCEPTION_HANDLER': 'user.utils.exception_handler',
  12. # Base API policies
  13. 'DEFAULT_RENDERER_CLASSES': [
  14. 'rest_framework.renderers.JSONRenderer',
  15. 'rest_framework.renderers.BrowsableAPIRenderer',
  16. ],
  17. 'DEFAULT_PARSER_CLASSES': [
  18. 'rest_framework.parsers.JSONParser',
  19. 'rest_framework.parsers.FormParser',
  20. 'rest_framework.parsers.MultiPartParser'
  21. ],
  22.  
  23. # 1.认证器(全局)
  24. 'DEFAULT_AUTHENTICATION_CLASSES': [
  25. # 'rest_framework.authentication.SessionAuthentication',# 使用session时的认证器
  26. # 'rest_framework.authentication.BasicAuthentication'# 提交表单时的认证器
  27. # 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',# 在DRF中配置JWT认证
  28. ],
  29.  
  30. # 2.权限配置(全局): 顺序靠上的严格
  31. 'DEFAULT_PERMISSION_CLASSES': [
  32. # 'rest_framework.permissions.IsAdminUser', # 管理员可以访问
  33. # 'rest_framework.permissions.IsAuthenticated', # 认证用户可以访问
  34. # 'rest_framework.permissions.IsAuthenticatedOrReadOnly', # 认证用户可以访问, 否则只能读取
  35. # 'rest_framework.permissions.AllowAny', # 所有用户都可以访问
  36. ],
  37.  
  38. # 3.限流(防爬虫)
  39. 'DEFAULT_THROTTLE_CLASSES': [
  40. 'rest_framework.throttling.AnonRateThrottle',
  41. 'rest_framework.throttling.UserRateThrottle',
  42. ],
  43. # 3.1限流策略
  44. 'DEFAULT_THROTTLE_RATES': {
  45. 'user': '1000/hour', # 认证用户每小时100次
  46. 'anon': '300/day', # 未认证用户每天能访问3次
  47. },
  48.  
  49. 'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'rest_framework.negotiation.DefaultContentNegotiation',
  50. 'DEFAULT_METADATA_CLASS': 'rest_framework.metadata.SimpleMetadata',
  51. 'DEFAULT_VERSIONING_CLASS': None,
  52.  
  53. # 4.分页(全局):全局分页器, 例如 省市区的数据自定义分页器, 不需要分页
  54. 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
  55. # 每页返回数量
  56. 'PAGE_SIZE': 10, # 默认 None
  57.  
  58. # 5.过滤器后端
  59. 'DEFAULT_FILTER_BACKENDS': [
  60. 'django_filters.rest_framework.DjangoFilterBackend',
  61. # 'django_filters.rest_framework.backends.DjangoFilterBackend', 包路径有变化
  62. ],
  63.  
  64. # 5.1过滤排序(全局):Filtering 过滤排序
  65. 'SEARCH_PARAM': 'search',
  66. 'ORDERING_PARAM': 'ordering',
  67. 'NUM_PROXIES': None,
  68.  
  69. # 6.版本控制:Versioning 接口版本控制
  70. 'DEFAULT_VERSION': None,
  71. 'ALLOWED_VERSIONS': None,
  72. 'VERSION_PARAM': 'version',
  73.  
  74. # Authentication 认证
  75. # 未认证用户使用的用户类型
  76. 'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser',
  77. # 未认证用户使用的Token值
  78. 'UNAUTHENTICATED_TOKEN': None,
  79.  
  80. # View configuration
  81. 'VIEW_NAME_FUNCTION': 'rest_framework.views.get_view_name',
  82. 'VIEW_DESCRIPTION_FUNCTION': 'rest_framework.views.get_view_description',
  83. 'NON_FIELD_ERRORS_KEY': 'non_field_errors',
  84.  
  85. # Testing
  86. 'TEST_REQUEST_RENDERER_CLASSES': [
  87. 'rest_framework.renderers.MultiPartRenderer',
  88. 'rest_framework.renderers.JSONRenderer'
  89. ],
  90. 'TEST_REQUEST_DEFAULT_FORMAT': 'multipart',
  91.  
  92. # Hyperlink settings
  93. 'URL_FORMAT_OVERRIDE': 'format',
  94. 'FORMAT_SUFFIX_KWARG': 'format',
  95. 'URL_FIELD_NAME': 'url',
  96.  
  97. # Encoding
  98. 'UNICODE_JSON': True,
  99. 'COMPACT_JSON': True,
  100. 'STRICT_JSON': True,
  101. 'COERCE_DECIMAL_TO_STRING': True,
  102. 'UPLOADED_FILES_USE_URL': True,
  103.  
  104. # Browseable API
  105. 'HTML_SELECT_CUTOFF': 1000,
  106. 'HTML_SELECT_CUTOFF_TEXT': "More than {count} items...",
  107.  
  108. # Schemas
  109. 'SCHEMA_COERCE_PATH_PK': True,
  110. 'SCHEMA_COERCE_METHOD_NAMES': {
  111. 'retrieve': 'read',
  112. 'destroy': 'delete'
  113. },
  114. }

案例中的相关配置

1.创建user/serializer.py 文件 用来写序列化

# -*- coding: utf-8 -*-
from rest_framework import serializers
from user.models import User
def address_validate(data):
return data
class UserSerializer(serializers.ModelSerializer):
address=serializers.CharField(max_length=255,min_length=5,validators=[address_validate])
def validate_address(self,data):
if data == "测试":
raise serializers.ValidationError('请填写实际地址')
return data
def validate_phone(self,data):
model=self.root.Meta.model
num=User.objects.filter(phone=data).count()
if num>0:
raise serializers.ValidationError('手机号')
return data
def validate(self,attrs):
return attrs
class Meta:
model=User
fields='__all__'
# fields=['username','address']
# exclude=['password']
read_only_fields=('',)
extra_kwargs={
"address":{
"min_length":5,
"default":"默认测试地址"
}
}
class UserInfoSerializer(serializers.Serializer):
id = serializers.CharField(read_only=True)# 普通字段,设置id为只读字段,不能修改
username = serializers.CharField(min_length=3,max_length=20,error_messages= {'required': '该字段必填'})# 显示普通字段
img = serializers.ImageField(required=False)
nick_name = serializers.CharField(max_length=20)
address = serializers.CharField(max_length=255)
xxx = serializers.SerializerMethodField(read_only=True)# 自定义显示(显示多对
class Meta:
model=User
def get_xxx(self,row):
users=row.username
return users
def create(self, validated_data):
return User.objects.create(**validated_data)
def update(self,instance,validated_data):
if validated_data.get('username'):
instance.username = validated_data['username']
instance.save()
return instance
def validate(self,attrs):
print(attrs)
if attrs.get("ussername")=='admin':
raise serializers.ValidationError('不能创建admin用户')
return attrs

class UserUnActiveSerializer(serializers.ModelSerializer):

class Meta:
model=User
fields=('id','username','is_active') #临时添加字段也需要写在这里
#fields="__all__" 所有字段

2.user/view.py 视图编写

from django.http import HttpResponse
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets
from rest_framework.authentication import BasicAuthentication, SessionAuthentication
from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter
from rest_framework.permissions import AllowAny, IsAdminUser, IsAuthenticated, IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.pagination import PageNumberPagination
from rest_framework.views import APIView
from rest_framework.permissions import BasePermission, SAFE_METHODS
from .models import User
from .serializers import UserSerializer, UserUnActiveSerializer
# import markdown

def index(request):
#需要认证才能访问的视图
return HttpResponse('hello')

# 分页(局部):自定义分页器 局部
class PageNum(PageNumberPagination):
# 查询字符串中代表每页返回数据数量的参数名, 默认值: None
page_size_query_param = 'page_size'
# 查询字符串中代表页码的参数名, 有默认值: page
# page_query_param = 'page'
# 一页中多的结果条数
max_page_size = 2

# 自定义权限(局部)
class MyPermission(BasePermission):
# has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
def has_permission(self, request, view):
print('has_perm')
# print(view.kwargs.get("pk"), request.user.id)
# """判断用户对模型有没有访问权"""
# 任何用户对使用此权限类的视图都有访问权限
if request.user.is_superuser:
# 管理员对用户模型有访问权
return True
elif view.kwargs.get('pk') == str(request.user.id):
# 携带的id和用户的id相同时有访问权
return True
return False

# has_object_permission 是用户过了 has_permission 判断有权限以后,再判断这个用户有 没有对一个具体的对象有没有操作权限
# 这样设置以后,即使是django admin管理员也只能查询自己user标的信息,不能查询其他用户的 单条信息

def has_object_permission(self, request, view, obj):
print('has_object_perm')
# """获取单个数据时,判断用户对某个数据对象是否有访问权限"""
if request.user.id == obj.id:
return True
return False

class UserViewSet(viewsets.ModelViewSet):
'''
完成产品的增删改查
'''
queryset = User.objects.all()
serializer_class = UserSerializer # 优先使用 get_serializer_class 返回的序列化器

# 1.认证: 自定义认证类, 自定义会覆盖全局配置
authentication_classes = (BasicAuthentication, SessionAuthentication) #
# 2.权限: 自定义权限类
permission_classes = (MyPermission,)

# 3.分页: 自定义分页器 覆盖全局配置
pagination_class = PageNum

# 4.限流: 自定义限流类
throttle_classes = [UserRateThrottle]

# 5.过滤: 指定过滤方法类, 排序方法类, 一个或多个
filter_backends = (DjangoFilterBackend, OrderingFilter) # 同时支持过滤和排序
# 5.1指定排序字段, 不设置, 排序功能不起效
ordering_fields = ('date_joined', 'id') # ?ordering=-id
# 5.2指定过滤字段, 不设置, 过滤功能不起效
filter_fields = ('username', 'phone', 'is_active') # ? username=tom&phone=&is_active=true

# 根据不同的请求, 获得不同的序列化器
def get_serializer_class(self):
if self.action == 'unactived':
return UserUnActiveSerializer
else:
return UserSerializer

@action(methods=['get'], detail=False)
def unactived(self, request, *args, **kwargs):
# 获取查询集, 过滤出未激活的用户
qs = self.queryset.filter(is_active=False)
# 使用序列化器, 序列化查询集, 并且是
ser = self.get_serializer(qs, many=True)
return Response(ser.data)

@action(methods=['get'], detail=False)
def actived(self, request, *args, **kwargs):
# 获取查询集, 过滤出未激活的用户
qs = self.queryset.filter(is_active=True)
# 使用序列化器, 序列化查询集, 并且是
ser = self.get_serializer(qs, many=True)
return Response(ser.data)

3.user/urls.py 路由

  1. from django.urls import path,include
  2. from user import views
  3.  
  4. from rest_framework.routers import SimpleRouter,DefaultRouter
  5.  
  6. from rest_framework.authtoken.views import obtain_auth_token
  7.  
  8. from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token
  9.  
  10. # 自动生成路由器方法,必须使用视图集
  11. router=DefaultRouter()
  12. router.register(r'user',views.UserViewSet)
  13.  
  14. urlpatterns = [
  15. path('index/',views.index),
  16. path('api-auth/',include('rest_framework.urls',namespace='rest_framework')),
  17.  
  18. ]
  19.  
  20. urlpatterns += router.urls # 模块地址

4.查询测试接口

 

1.DRF初始化的更多相关文章

  1. modelviewset与apiview

    modelviewset(认证,权限,限流,序列化,分页,过滤,排序) 1.DRF初始化 1.认证(让用户登录) 2.权限(根据不同用户角色,可以操作不同的表) 3.限流(限制接口访问速度) 4.序列 ...

  2. ModelViewSet里的过滤、排序、分页、序列化设置

    1.DRF初始化 1.认证 2.权限 3.限流 4.序列化 5.分页 6.版本  7.过滤 8.排序 1.1安装DjangoRestFramework pip install djangoresfra ...

  3. day1(ModelViewSet序列化限流排序)

    1.DRF初始化 1.认证 2.权限 3.限流 4.序列化 5.分页 6.版本  7.过滤 8.排序 1.1安装DjangoRestFramework pip install djangoresfra ...

  4. ModelViewSet+ModelSerializer使用

    1.DRF初始化 DRF框架的8个核心功能 1.认证(用户登录校验用户名密码或者token是否合法) 2.权限(根据不同的用户角色,可以操作不同的表) 3.限流(限制接口访问速度) 4.序列化(返回j ...

  5. drf相关问题

    drf自定义用户认证: 登录默认 使用django的ModelBackend,对用户名和密码进行验证.但我们平时登录网站时除了用户名也可以用邮箱或手机进行登录,这就需要我们自己扩展backend 一. ...

  6. django drf 基础学习2

    DRF基本程序调用一 models初步编写  1 编写model.py    from django.db import models 导入    class dbinfo(models.Model) ...

  7. DRF 认证、权限、限制

    DRF 认证.权限.限制   认证: 定义一个用户表和一个保存用户的Token表 # ======================day96======================= class ...

  8. DRF 版本 认证

    DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢大家都知道我们开发项目是有多个版本的 当我们项目越来越更新~版本就越来越多我们不可能新的版本出了~以前旧的版本 ...

  9. DRF 权限和频率

    Django Rest Framework 权限组件 DRF的权限 权限组件源码解析 我们之前说过了DRF的版本和认证~也知道了权限和频率跟版本认证都是在initial方法里初始化的~~ 其实我们版本 ...

随机推荐

  1. Android Studio 自定义字体显示英文音标

    android:fontFamily="serif" 网上查了很多自定义字体的方式,或多或少都有些麻烦,最后还是尝试着认为内置字体不应该实现不了英文音标问题,就一个一个字体试了一下 ...

  2. Centos-修改文件访问和修改时间-touch

    touch 如果文件存在,则改变文件的访问时间和修改时间,如果不存在则创建一个空文件 相关选项 -a   更改文件访问时间为当前系统时间 -m     更改文件修改时间为当前系统时间 -c   如果文 ...

  3. 090 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 04 使用包进行类管理(2)——导入包

    090 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...

  4. 【转载】绕过CDN找到源站的思路

    [原文:https://mp.weixin.qq.com/s/8NUvPqEzVjO3XbmCBukUvQ] 绕过CDN的思路 网上有很多绕过CDN的思路,但是存在很多问题,以下是收集并总结的思路.站 ...

  5. P4231 三步必杀

    题目描述 问题摘要: N个柱子排成一排,一开始每个柱子损伤度为0. 接下来勇仪会进行M次攻击,每次攻击可以用4个参数l,r,s,e来描述: 表示这次攻击作用范围为第l个到第r个之间所有的柱子(包含l, ...

  6. WSL2 bug

    错误现象 Stdout: Stderr: 2020/05/27 20:01:37 resolving /mnt/host/c/Program Files/Docker/Docker/resources ...

  7. S3C6410中断系统

    S3C6410的中断主要改进是. 增加中断向量控制器,这样在S3C2440里需要用软件来跳转的中断处理机制,在S3C6410完全由硬件来跳转.你只要把ISR地址是存在连续向量寄存器空间,而不是象S3C ...

  8. Java bean 链式获取成员变量无需判空的工具设计

    Java bean 链式获取成员变量无需判空的工具设计 本篇文章已发布至公众号 Hollis 对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者 ...

  9. [Docker] redis 全配置

    启动容器,加载配置文件并持久化数据 docker run -d --privileged=true -p 6379:6379 --restart always -v /usr/redis/conf:/ ...

  10. 多测师讲解selenium--常用关键字归纳-_高级讲师肖sir

    常见的定位方式: 1.通过id定位 id=kw 2.通过name定位 name=wd 3.通过xpath相对路径定位:xpath=//*[@id="kw"] 4.通过两个属性值定位 ...