首页 > 编程语言 >drf(初始drf,restfull规范 ,源码)

drf(初始drf,restfull规范 ,源码)

时间:2023-09-20 13:34:36浏览次数:46  
标签:self request api restfull https view com 源码 drf

一 web开发模式

# 前后端混合开发(前后端不分离):通过模版语法,在服务器上处理好html的内容(组合字符串),返回给浏览器一堆字符串(字符串封装到respons对象里),浏览器在渲染

# 前后端分离:只专注于写后端接口,返回json、xml格式
        # xml比json笨重



# 补充:什么是动态页面(需要查数据库的),什么是静态页面(内容写死的页面)
# 访问量大的home页面,进行静态页面优化

二 API接口

# 通过网络,规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介
Application Programming Interface

三 postman的使用

# postman是当前最好用的,模拟发送http请求的工具
#  解析json的网站
www.json.cn

# 请求头中User-Agent:客户端的类型
# 请求头中加其他参数
# url的末尾加/,浏览器中不加,是因为两次get,重定向自动给加上去的

四 restfull规范

'''
1. 什么是RESTFUll

    RESTfull 是目前最流行的 API 设计规范,用于 Web 数据接口的设计。

    REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”

    REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态

    所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
'''

十条规范

1 数据的安全保障
  • url链接一般都采用https协议进行传输

    注:采用https协议,可以提高数据交互过程中的安全性

抓包工具:fiddler,chales

2 接口特征表现
3 多数据版本共存

就比如手机app,有 些升级了,有些还没升级,没升级的,就是用的老版本

新升级的,用的新版本

4 数据即是资源,均使用名词(可复数)
5 资源操作由请求方式决定

6 过滤信息(filtering,或称查询参数)

  • 如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。下面是一些常见的参数。

https://api.baidu.com/v1/books?limit=10:指定返回记录的数量
https://api.baidu.com/v1/books?offset=10:指定返回记录的开始位置。
https://api.baidu.com/v1/books?page=2&per_page=100:指定第几页,以及每页的记录数。
https://api.baidu.com/v1/books?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
https://api.baidu.com/v1/books?animal_type_id=1:指定筛选条件
7.响应状态码

7.1 正常响应

  • 响应状态码2xx

    • 200:常规请求

    • 201:创建成功

7.2 重定向响应

  • 响应状态码3xx

    • 301:永久重定向

    • 302:暂时重定向

7.3 客户端异常

  • 响应状态码4xx

    • 403:请求无权限

    • 404:请求路径不存在

    • 405:请求方法不存在

7.4 服务器异常

  • 响应状态码5xx

    • 500:服务器异常

8 错误处理,应返回错误信息,error当成key

发生错误时不要响应200状态码,有一种不恰当的做法是,即使发生错误,也返回200状态码,把错误信息放在数据体里面,就像下面这样。

{
  "status": "failure",
  "data": {
    "error": "Expected at least two items in list."
  }
}
9 返回结果,针对不同操作,服务器向用户返回的结果应该符合一下规范
GET /collection:返回资源对象的列表(数组),一般是[{"id":1,"name":"a",},{"id":2,name:"b"},]这种类型
GET /collection/resource:返回单个资源对象, 一般是查看的单条数据 {"id":1,"name":'a'}
POST /collection:返回新生成的资源对象 , 一般是返回新添加的数据信息, 格式一般是{}
PUT /collection/resource:返回完整的资源对象  一般时返回更新后的数据,{}
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档  一般返回一个空字符串
10 Hypermedia API,提供链接

RESTful API最好做到Hypermedia,即返回结果中提供链接,API 的使用者未必知道,URL 是怎么设计的。

一个解决方法就是,在回应中,给出相关链接,便于下一步操作。

这样的话,用户只要记住一个 URL,就可以发现其他的 URL。

{
  ...
  "feeds_url": "https://api.github.com/feeds",
  "followers_url": "https://api.github.com/user/followers",
  "following_url": "https://api.github.com/user/following{/target}",
  "gists_url": "https://api.github.com/gists{/gist_id}",
  "hub_url": "https://api.github.com/hub",
  ...
}

五 drf的安装和简单使用

# 安装:pip install djangorestframework=3.10.3
# 使用:
1 在settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'rest_framework'
]
2 在models.py中写表模型
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    author = models.CharField(max_length=32)
3 新建一个序列化类
app01下建一个ser.py
from rest_framework.serializers import ModelSerializer
from app01.models import Book


class BookModelSerializer(ModelSerializer):
     class Meta:
          model = Book
          fields = "__all__"
4 在视图函数中写视图类,views.py
from rest_framework.viewsets import ModelViewSet
from app01.models import Book
from app01.ser import BookModelSerializer


# Create your views here.
class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer
    
5 写路由关系,urls.py
from app01 import views
from rest_framework.routers import DefaultRouter

router = DefaultRouter()  # 可以处理视图的路由器
router.register('book', views.BookViewSet)  # 向路由中注册视图集

# 将路由中的所有路由信息追到django的路由列表中

urlpatterns = [
    path('admin/', admin.site.urls),
]

# 两个列表相加,就是将列表rooter.urls的值追加到urlpatterns,for循环,再.append
urlpatterns += router.urls

六 CBV源码

# ModelViewSet继承View(django原生View)
# APIView继承View

# 先读View
# views.py
from django.views import View
class Books(View):
    def get(self, request):
        return HttpResponse('ok')

# urls.py
path('books/', views.Books.as_view()),
'''
在这个地方应该写个函数的内存地址,views.Books.as_view()执行完,是个函数内存地址,Books继承了Views类,里面的as_view是类方法,所有由Books.as_view()
'''
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

    '''
    因return view,view是as_view的闭包函数,Books.as_view()的调用,就是调用view,类的绑定方法,把类当对象传入。
    '''  
    @classonlymethod
    # 路由中,一般没有传参, **initkwargs没有值
    def as_view(cls, **initkwargs):
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)    # 实例化,book对象
            self.setup(request, *args, **kwargs)
            return self.dispatch(request, *args, **kwargs)
            # dispatch方法,先对象里找,没有去类中找,类中没有就去给类的父类找
        return view
    
    def setup(self, request, *args, **kwargs):
        if hasattr(self, 'get') and not hasattr(self, 'head'):
        self.head = self.get
        # 传入的request,赋值给对象
        self.request = request
        
    def dispatch(self, request, *args, **kwargs):
        if request.method.lower() in self.http_method_names:
            # 反射取值,得到get的内存地址
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
            # 内存地址加括号并传参,就是传参调用函数
        return handler(request, *args, **kwargs)

七 APIView源码

1 一切皆对象

函数也是对象

def foo(a,b):
    return a+b

foo.name = 'lq'    # 一切皆对象

print(foo(2,3))

print(foo.name)  # lq’

2 局部禁用csrf

# 在视图函数上加装饰器@csrf_exempt
# csrf_exempt(view)  这么写和在视图函数上加装饰器是一模一样

3 源码

# urls.py
path('booksapiview/', views.BooksAPIView.as_view())

# views.py
from rest_framework.views import APIView
class BooksAPIView(APIView):
    def get(self, request):    
        return HttpResponse('ok')
    
# APIView的as_view方法(类的绑定方法)
@classmethod
def as_view(cls, **initkwargs):
    # 调用父类,就是django的View类的as_view方法
    view = super().as_view(**initkwargs)
    # 把函数当对象,进行属性赋值
    view.cls = cls
    view.initkwargs = initkwargs
    # Note: session based authentication is explicitly CSRF validated,
    # 以后所有的请求,都没有csrf认证了,只要继承了APIView,就没有csrf的认证
    # all other authentication is CSRF exempt.
    # 就是给函数加装饰器@csrf_exempt
    return csrf_exempt(view)

# view = super().as_view(**initkwargs),--->django的View类中的as_view方法--->return self.dispatch(request, *args, **kwargs)--->回到APIView类的dispatch方法

# 类的方法调用,先从对象找--->产生对象的类中找--->父类--->父类的父类

def dispatch(self, request, *args, **kwargs):
    self.args = args
    self.kwargs = kwargs
    # 重新包装成一个request对象,以后再用的request对象,就是新的request对象了,initialize_request,是Request类的一个实例化的返回
    request = self.initialize_request(request, *args, **kwargs)
    self.request = request
    self.headers = self.default_response_headers  # deprecate?

    try:
        # 三大认证模块(request是新的request)
        self.initial(request, *args, **kwargs)

        # Get the appropriate handler method
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(),
                              self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
            # 响应模块
            response = handler(request, *args, **kwargs)

    except Exception as exc:
        # 异常模块
        response = self.handle_exception(exc)
    # 渲染模块,根据客户端的不同(浏览器,postman),渲染不同的数据
    self.response = self.finalize_response(request, response, *args, **kwargs)
    return self.response

Request类的源码

# from rest-framework.request import Request
# 只要继承了APIView,视图类中的request对象,都是新,也就是上面新的self.initialize_request(request, *args, **kwargs)
# 原生的request在新的request._request

class Request:
    def __init__(self, request, parsers=None, authenticators=None,
                 negotiator=None, parser_context=None):
        # 二次封装request,将原生request作为drf-request对象的_request属性
        self._request = request
        self.parsers = parsers or ()
        self.authenticators = authenticators or ()
        self.negotiator = negotiator or self._default_negotiator()
        self.parser_context = parser_context
        self._data = Empty
        self._files = Empty
        self._full_data = Empty
        self._content_type = Empty
        self._stream = Empty

# 以后使用request对象,就像使用之前的request是一模一样(因为重写了__getattr__方法,request.methed用法是一样的,不用request._request.methed,request.属性的时,自动触发__getattr__方法
def __getattr__(self, attr):
    try:
        # 放射,从原生request对象中取属性方法
        return getattr(self._request, attr)
    except AttributeError:
        # 改进,不仅可以点取属性,还可以用[]的形式取属性,类.__dict__
        return self.__getattribute__(attr)
    
# request.data 不是属性,是@property修饰的一个方法
# 还有返回的一个字典,post请求不管使用什么编码(urldecode、formdata、json),传过来的数据,都在request.data,
@property
def data(self):
    if not _hasattr(self, '_full_data'):
        self._load_data_and_files()
        return self._full_data
    
# GET方发虽然重写了,还是request.GET,
@property
def query_params(self):
    return self._request.GET
    
    # 视图类中
    print(request.query_params) 
    '''
        也是GET过来的数据,作者给改了个名,认为query_params是查询集,
        更符合drf规范,本来get过来的数据就是查询集
        '''        
    print(request.GET)
    

 

标签:self,request,api,restfull,https,view,com,源码,drf
From: https://www.cnblogs.com/coderxueshan/p/17717082.html

相关文章

  • 基于微信小程序的在线考试系统设计与实现-计算机毕业设计源码+LW文档
    一、研究的背景意义随着计算机的持续发展,人类进入信息化时代,各种软件和管理系统层出不穷,软件已成为提高办公质量和经济增长的重要手段,由此带来了许多新兴行业。比如在线购物,京东商城、慕课和在线学习的成功有目共睹。基于互联网的管理平台,收集和整理各类信息,这些信息以有序的方式......
  • 基于java的学生课程管理系统-计算机毕业设计源码+LW文档
    计算机技术的发展,改变了的生产生活方式。在高校,越来越多的教务管理使用管理系统进行管理,用来提高管理效率。在传统的教学管理中,高校往往通过大量的人力和物力进行管理,通过手工记录课程信息,统计科目资料。传统的管理方法容易出错,而学生课程管理系统可以帮助教师管理课程信息,查看课程......
  • 基于springboot智能考试系统的设计与实现-计算机毕业设计源码+LW文档
    摘要随着信息技术的发展,管理系统越来越成熟,各种企事业单位使用各种类型的管理系统来提高工作效率,从而降低手工操作的弊端。我国政府一直以来都非常重视中学阶段教育的发展,近几年来学生人数逐渐增加,对在线考试的需求越来越多。因此,通过开发基于springboot智能考试系统来提高学习效......
  • 基于java的高校智慧课堂管理系统的设计与实现-计算机毕业设计源码+LW文档
    一、研究的背景和意义研究背景:随着计算机网络技术和互联网技术的飞速发展,社会的快速进步和人们生活质量的不断提高,人们的文化生活受到了极大的变化。而我们国家的教育也在随着社会的发展发生巨大的改变。在计算机技术的飞速发展前提下,特别是智能Android操作系统的问世,基于移动设......
  • 基于java的酒店管理系统的设计与实现-计算机毕业设计源码+LW文档
    摘要信息化的迅速发展,对人们的衣食住行产生了很大影响。越来越多的人习惯并依赖于通过信息技术和智能化的形式来处理日常各类事物。为了满足住店用户预定酒店的需要,以及适应现代化酒店管理的需求,决定开发酒店管理系统。帮助会员快速的在线预定,提高了预定效率。本系统是选择面向......
  • zone.js由入门到放弃之五——NgZone & ApplicationRef源码分析
    啸达同学刚写zone.js系列就说过,NgZone影响着Angular中的变更检测,历时一个多月的笔耕不辍,终于到了他初次下笔时的目的地~zone.js系列zone.js由入门到放弃之一——通过一场游戏认识zone.jszone.js由入门到放弃之二——zone.jsAPI大练兵zone.js由入门到放弃之三——zone.js源码分析......
  • Vue源码学习(七):合并生命周期(混入Vue.Mixin)
    好家伙, 1.使用场景现在来,来想一下,作为一个使用Vue的开发者,假设现在我们要使用created(),我们会如何使用1.1. .vue文件中使用<template><div><h1>{{message}}</h1></div></template><script>exportdefault{created(){this.message='......
  • 想查看某些网站源码,结果发现网站F12被禁用,怎么解决?
    当我们访问某些网站的时候,发现网站是禁用了F12和右键功能的。比如想保存网页上的一些文字或图片等,新手不知道怎么破除。下面分享给大家几种方法:1、打开网页后,鼠标点进浏览器地址栏,再按F12键,就可以用了。2、打开网页后,鼠标点进浏览器地址栏,再按快捷键Ctrl+U,就可以用了。3、可以......
  • DRF之分页类源码分析
    【一】分页类介绍DjangoRESTframework(DRF)是一个用于构建WebAPI的强大工具,它提供了分页功能,使你能够控制API响应的数据量。在DRF中,分页功能由分页类(PaginatorClass)来管理。【二】内置分页类在DRF中,分页类通常位于rest_framework.pagination模块中,它们用于分割长列表或......
  • DRF之排序类源码分析
    【一】排序类介绍在DjangoRESTframework(DRF)中,排序类用于处理API端点的排序操作,允许客户端请求按特定字段对数据进行升序或降序排序。排序类是一种特殊的过滤类DRF提供了内置的排序类,并且你也可以自定义排序类以满足特定的需求。【二】内置排序类OrderingFilterrest_f......