1. ApiView

定义一个cbc视图

class BookView (APIView):pass

re_path(r"books/$", views.BookView.as_view(),name = "books"),

re_path(r"books/$", views.类下的View.as_view(),name = "books"),

一单有请求进来访问books/:  view(request) ========APIView 类下的dispatch( )执行

2.def dispatch():

  # 初始化操作

  ( 1 )构造新的request: 

     self.request = self.initial_request( )  

  # self.request._request

  # self.request.GET

  # self.reqeust.data

  ( 2 ) 执行组件

    # 认证,权限,频率

  认证 : request.user

    self.initial (request, *args , **kwargs)

    # 认证组件,他调用了新创建的request.user方法
    self.perform_authentication(request)
      认证:request.user
      self.initial(request,*args,**kwargs)
        ========# 认证组件
            self.perform_authentication(request)
                request.user
                  ========
                       for authenticator in self.authenticators: {# toekn}
        # 我取了self.authenticators 中的一个属性
for authenticator in self.authenticators: # [TokenAuth()]执行的返回值
try:
# 意思就是你如果没有自定义这个类就会抛错
user_auth_tuple = authenticator.authenticate(self)# 我自定义的这个方法
except exceptions.APIException:
self._not_authenticated()
"""
有异常了 可以用rasie决定异常了该做什么
不过 即使没有异常 也可以raise来定义满足特定条件后抛弃什么异常
"""
raise
# 这个条件成立
if user_auth_tuple is not None:
self._authenticator = authenticator # 赋值 [TokenAuth()]
# <rest_framework.request.Request object at 0x036BC390>
self.user, self.auth = user_auth_tuple # 自定义方法的返回值 赋值了给 user, auth
return

    # 权限组件
    self.check_permissions(request)
      ========
                
        # 这里我for循环了一个方法,这个方法就是我定义的那个类
for permission in self.get_permissions():
# <rest_framework.permissions.AllowAny object at 0x034F1810>
# 我们得确认下 permission.has_permission(request, self) 发生了什么
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)

        
    # 频率组件
    self.check_throttles(request)
  (3)分发:
    # Get the appropriate handler method
  if request.method.lower() in self.http_method_names:
# self = Publish,反射类中的get方法如果有我就封装到handler里面,如果你没有定义方法我我也就返回一个错误信息
   handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
  else:
  handler = self.http_method_not_allowed
# 也就是说这个地方要么就是调用我Publish的get方法和post方法,要不就抛错误信息   response = handler(request, *args, **kwargs)
4.序列化组件
1.serializers.Serializer 初级版
from django.shortcuts import render, HttpResponse, redirect
from django.views import View
from app01 import models
from rest_framework.views import APIView # 一.定义一个反序列的类
from rest_framework import serializers
from rest_framework.response import Response

# 为queryset, model对象做序列化,只要你定义了name和addr我都能给你反序列化 class PublishSerializers(serializers.Serializer):    name = serializers.CharField()    addr = serializers.CharField()
#使用
class PublishView(APIView):
# 查询数据
def get(self, request):
# first inquire database
publish = models.Publisher.objects.all()
# data put serializers data packging
bs = PublishSerializers(publish, many=True) # many=True多个对象
# return
return Response(bs.data) # 一对多 多对多的使用
class BookSerializers(serializers.Serializer):
title = serializers.CharField()
pub_date = serializers.DateField()
# 反序列化一对多字段返回的是__str__数据
publish = serializers.CharField(source="publish.addr") # source 可以指定返回的一对多的字段
# authors=serializers.CharField(source="authors.all") # 指定序列化多对多的字段
authors = serializers.SerializerMethodField() # 多对多字段序列化方法,这个函数必须是get_authors,因为这个字段在是多对多
def get_authors(self, obj):
temp = []
for obj in obj.authors.all():
temp.append(obj.name)
return temp
#使用
class PublishView(APIView):
# 查询数据
def get(self, request):
# first inquire database
book = models.Book.objects.all()
# data put serializers data packging
bs = BookSerializers(book, many=True) # many=True多个对象
# return
return Response(bs.data)
    bs = PublishModelSerializers(data=request.data, many=True)  # post不需要定义many=Ture

        if bs.is_valid():
bs.save() # 保存

# 更多操作

        ps = PublishModelSerializers(publish, data=request.data)
# if ps pass verify
if ps.is_valid():
ps.save() #更新

2.serializers.ModelSerialize 中级版
class BookModelSerializers(serializers.ModelSerializer):
# 自定义publish字段超链接路径
# publish_url = serializers.HyperlinkedIdentityField(view_name='detailpublish',
# lookup_field='publish_id',
# lookup_url_kwarg='pk',
# )
# publish = serializers.CharField(source="publish.id")
"""
# view_name参数 进行传参的时候是参考路由匹配中的name与namespace参数
# lookeup_field参数是根据在UserInfo表中的连表查询字段group_id
# look_url_kwarg参数在做url反向解析的时候会用到
""" # 重写save中的create方法
# def create(self, validated_data):
# # create 方法之前也可以单独pop在添加
# """
# author = validated_data.pop[title]
# 然后再进行额外自己添加
# obj = Book.objecte.create(**validated_data)
# obj.authors.add(*authors)
# """
# publish_id = validated_data["publish"]["id"]
# book = models.Book.objects.create(title=validated_data["title"], pub_date=validated_data["pub_date"],
# publish=models.Publisher.objects.filter(pk=publish_id).first()
# )
# book.authors.add(*validated_data["authors"])
# return book class Meta:
model = models.Book
# fields = ['id', 'title', 'pub_date', 'publish', 'authors']
fields = "__all__"
depth = 0 ## 0 ~ 10
# 自动向内部进行深度查询,就是查询的比较详细 depth表示查询层数

5.视图组件
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework import viewsets
from django.views import View
from app01 import models
from rest_framework.views import APIView
# 版本1:
class PublishDetaiView(APIView):
# 将这个pk设置成和lookup_url_kwarg='pk' 一样的值,不然加后缀会取不到值
def get(self, request, id): # id 不要放到request前面
# 查询数据库
publish = models.Publisher.objects.filter(pk=id)
# 封装打包序列化数据
bs = PublishModelSerializers(publish, many=True) # many=True多个对象
# Response 会直接返回josn数据格式
ret = Response(bs.data) return ret # # 修改数据(前端指定id值后,在data中输入k:v即可change数据)
def put(self, request, id):
# inquire database
publish = models.Publisher.objects.filter(pk=id).first()
# data= form request.data client
ps = PublishModelSerializers(publish, data=request.data)
# if ps pass verify
if ps.is_valid():
ps.save()
return Response(ps.data)
else:
return Response(ps.errors) # 删除数据(功能还未实现)
def delete(self, request, id):
print(type(id), 5555555555555)
models.Publisher.objects.filter(id=id).delete()
return Response("删除成功")

# 版本 2

class BOOK(GenericAPIView, mixins.ListModelMixin):
queryset = models.School.objects.all()
serializer_class = app01_serializers.SchoolSerializer def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs) class BOOK(GenericAPIView, mixins.RetrieveModelMixin, mixins.CreateModelMixin):
queryset = models.School.objects.all()
serializer_class = app01_serializers.SchoolSerializer def get(self, request, pk, *args, **kwargs):
return self.retrieve(request, pk, *args, **kwargs) def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs

# 版本3 基于通用类

# 封装了3层
class AuthorView(viewsets.ModelViewSet):
# queryset serializer 这两个方法一定要定义成这个不然取不到值
queryset = models.Author.objects.all()
serializer_class = AuthorModelSerializers # 封装了3层
class AuthorDetaiView(viewsets.ModelViewSet):
# authentication_classes = [TokenAuth]
# queryset serializer 这两个方法一定要定义成这个不然取不到值
queryset = models.Author.objects.all()
serializer_class = AuthorModelSerializers

# 版本四

    re_path('^authors/$', views.AuthorView.as_view({"get": "list", "post": "create"})),
# View(request) ======APIView:dispatch()
re_path('^author/(?P<pk>\d+)/$',
views.AuthorDetaiView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),

  流程:

    请求一旦访问/authors/:

    View()

            # Bind methods to actions
# This is the bit that's different to a standard view
for method, action in actions.items():
handler = getattr(self, action) # self.list self.creat
setattr(self, method, handler) # self.get self.post
        return self.dispatch(request, *args, **kwargs)

          APIView 类下的self.dispatch

           #分发 执行视图
# Get the appropriate handler method
if request.method.lower() in self.http_method_names:
# self = Publish,反射类中的get方法如果有我就封装到handler里面,如果你没有定义方法我我也就返回一个错误信息
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# 也就是说这个地方要么就是调用我Publish的get方法和post方法,要不就抛错误信息 response = handler(request, *args, **kwargs)
        return self.response

6.认证频率组件
import time

# 自定义限制
VISIT_RECORD = {}
class VisitRateThrottle(object):
def __init__(self):
self.history = None def allow_request(self, request, view): """
自定义频率限制60秒内只能访问三次
"""
# 获取用户IP
ip = request.META.get("REMOTE_ADDR")
# 获取当前时间戳
timestamp = time.time() # 如果当前访问ip没有在列表中 我就新建一个IP访问记录
if ip not in VISIT_RECORD:
VISIT_RECORD[ip] = [timestamp, ]
# 可以通过验证
return True # 如果列表中有值,我就取当当前ip地址 赋值给变量
history = VISIT_RECORD[ip]
self.history = history
# 在列表头部 插入一个时间戳
history.insert(0, timestamp)
# 如果列表有值,最先插入的值小于 当前值-60 ,tiemstamp是当前时间是在增加的
while history and history[-1] < timestamp - 60:
# pop 取出 最后一个条件成立的值
history.pop()
# 列表中的时间戳 大于3 就返回falsse,否则通过
if len(history) > 3:
return False
else:
return True def wait(self):
# 返回给前端还剩多少时间可以访问
timestamp = time.time()
# 求出还剩多少时间可以访问
return 60 - (timestamp - self.history[-1])
7.解析器 和渲染器
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser
parser_classes = [JSONParser,FormParser]

8,解析器(路由控制)
针对:
    
re_path(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),
re_path(r'^author/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailauthor"),
class AuthorModelView(viewsets.ModelViewSet):
   queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
 

 


												

Django源码分析rest_framework 关于re_path('^publish/', views.PublishView.as_view()总结的更多相关文章

  1. django源码分析 python manage.py runserver

    django是一个快速开发web应用的框架, 笔者也在django框架上开发不少web应用,闲来无事,就想探究一下django底层到底是如何实现的,本文记录了笔者对django源码的分析过程 I be ...

  2. Django源码分析之启动wsgi发生的事

    前言 ​ 好多人对技术的理解都停留在懂得使用即可,因而只会用而不会灵活用,俗话说好奇害死猫,不然我也不会在凌晨1.48的时候决定写这篇博客,好吧不啰嗦了 ​ 继续上一篇文章,后我有个问题(上文:&qu ...

  3. django源码分析——本地runserver分析

    本文环境python3.5.2,django1.10.x系列 1.根据上一篇文章分析了,django-admin startproject与startapp的分析流程后,根据django的官方实例此时 ...

  4. 2、Django源码分析之启动wsgi发生了哪些事

    一 前言 Django是如何通过网络socket层接收数据并将请求转发给Django的urls层? 有的人张口就来:就是通过wsgi(Web Server Gateway Interface)啊! D ...

  5. django源码分析

    原文网址 https://www.jianshu.com/p/17d78b52c732?utm_campaign=maleskine&utm_content=note&utm_medi ...

  6. django源码分析——处理请求到wsgi及视图view

    本文环境python3.5.2,django1.10.x系列 根据前上一篇runserver的博文,已经分析了本地调试服务器的大致流程,现在我们来分析一下当runserver运行起来后,django框 ...

  7. django源码分析 LazySetting对象

    一.django中通过LazySetting对象来获取项目的配置,LazySetting对象有什么特性?为什么使用这个对象? LazySetting顾名思义,就是延迟获取配置内容.比如,我们定义了一个 ...

  8. django源码分析——静态文件staticfiles中间件

    本文环境python3.5.2,django1.10.x系列 1.在上一篇文章中已经分析过handler的处理过程,其中load_middleware就是将配置的中间件进行初始化,然后调用相应的设置方 ...

  9. Django源码分析之程序执行入口分析

    一般我们开启一个django项目,最简单的方法是进入project 目录,这时目录结构是这样的 然后我们执行python manage.py runserver,程序就开始执行了. 那django是如 ...

随机推荐

  1. win10 远程连接怎么设置快捷方式

    在桌面空白处右键,选择新建快捷方式,然后输入命令:C:\windows\system32\mstsc.exe,点击下一步,然后输入快捷方式名称:远程连接,点击确定即可.

  2. authenticate的执行流程与重写

    流程 1.authenticate调用的是_get_backends函数 def authenticate(request=None, **credentials): for backend, bac ...

  3. Django——用户认证

    Django--用户认证 用户与Authentication(身份验证) Django 用户认证系统处理用户帐号,组,权限以及基于cookie的用户会话. 这个系统一般被称为 auth/auth (认 ...

  4. C++ 多态详解及常见面试题

    今天,讲一讲多态: 多态就是不同对象对同一行为会有不同的状态.(举例 : 学生和成人都去买票时,学生会打折,成人不会) 实现多态有两个条件: 一是虚函数重写,重写就是用来设置不同状态的   二是对象调 ...

  5. 在bat批处理中简单的延时方法

    使用for命令: 延时1s左右的方法: @echo off echo %time% ,,) do echo %%i>nul echo %time% pause %time%是用来显示延时时间,实 ...

  6. SQL Server 索引优化 ——索引缺失

    本文我们将重点给出动态视图法发现数据库中缺失的索引.对于索引的调整和新建将不在本文阐述范围,后续将陆续分享相关经验. sys.dm_db_missing_index_details 缺失索引明细,包括 ...

  7. IDEA使用@Data注解,类调用get、set方法标红的解决办法

    1.在setting中,下载lombok插件,安装完成后重启idea

  8. Linux系统中五款好用的日志分析工具

    监控网络活动是一项繁琐的工作,但有充分的理由这样做.例如,它允许你查找和调查工作站和连接到网络的设备及服务器上的可疑登录,同时确定管理员滥用了什么.你还可以跟踪软件安装和数据传输,以实时识别潜在问题, ...

  9. BUAA OO 2019 第三单元作业总结

    目录 总 JML规格化设计 理论基础 工具链 规格验证 验证代码 代码静态检查 自动生成测试样例 生成结果 错误分析 作业设计 第九次作业 架构 代码实现 第十次作业 架构 代码实现 第十一次作业 架 ...

  10. CSS ID选择器&通配选择器

    ID选择器 ID(IDentity)是编号的意思,一般指定标签在HTML文档中的唯一编号.ID选择器和标签选择器.类选择器的作用范围不同. ID选择器仅仅定义一个对下对象的样式,而标签选择器和类选择器 ...