Django Restful Framework

你在浏览器中输入了一个地址的时候发生了什么事情?

1.HOST
2.DNS
3.HTTP/HTTPS协议 发送一个协议
4.进入了实现了WSGI协议的服务器(wsgiref uwsgi(C语言实现,多线程,多进程,PHP,TOMCAT))
5.请求进入Django
6. 前后端不分离:中间件->路由分发->对应的视图函数->找到模板,渲染数据-> 返回模板的字符串
	前后端分析:中间件->路由分发->返回JSON数据

Django源代码解读

graph TD
A[路由匹配到book]-->B(执行as_view)
B --> C[执行dispath方法]
C --> D{在HTTP请求中}
D -->|是HTTP请求| E[利用反射获得该请求内存地址,并执行]
D -->|不是HTTP请求| F[405错误方法不允许]

应用

我们也可以重写dispatch方法,做登陆验证,或者请求限制,做访问频率验证

返回数据的Json数据时候可以使用JsonResonpe 使用列表转换的时候,要带上safe=False

Restful规范

1.使用API与用户通讯,总是使用https
2.域名有区分

3.版本
可以放在URL地址中
也可以放在请求头中(利用request.Meta进行取值)

4.路径,路径上的任何参数都是资源,均使用名词
5.通过METHOD区分不同的操作
GET :从服务器取出资源(一项或多项)
POST :在服务器新建一个资源
PUT :在服务器更新资源(客户端提供改变后的完整资源)
PATCH :在服务器更新资源(客户端提供改变的属性)
DELETE :从服务器删除资源
6.过滤,通过在url上传参的形式传递搜索条件
https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数
https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件

7.状态码

OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
NO CONTENT - [DELETE]:用户删除数据成功。
INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

8.错误处理,应该返回错误信息

?

{
    ``error: ``"Invalid API key"
}

9.返回结果

GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档

10.Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么

{"link": {
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}

drf 应用

? -安装:

		-pip3 install djangorestframework

使用

		-第一步,再写视图,都写cbv
			from rest_framework.views import  APIView
			class Books(APIView):
				pass
		-在setting中配置
			INSTALLED_APPS= [
					。。。。。
				‘rest_framework‘
			]
	-源码分析:
		继承了APIView 之后:
			-1 所有的请求都没有csrf的认证了
			-2 在APIView中as_view本质还是调用了父类的as_view(View的as_view)
			-3 as_view中调用dispatch  -----》这个dispatch是APIView的dispatch

graph
TD
A[路由匹配到book]-->B(执行as_view)
B --> C[执行dispath方法]
C --> D{在HTTP请求中}
D -->|是HTTP请求| E[利用反射获得该请求内存地址]
D -->|不是HTTP请求| F[405错误方法不允许]

DRF源码解读

request类中实现的其他方法

总结

现在我们可以在views中一旦继承了drf的APIview可以调用

		-1 原生的request是self._request
		-2 取以post形式提交的数据,从request.data中取(urlencoded,formdata,json格式)
		-3 query_params 就是原生request的GET的数据
		-4 上传的文件是从FILES中取
		-5 (重点)其他的属性,直接request.属性名(因为重写了__getattr__方法)

序列化组件的使用

		-使用drf的序列化组件
			-1 新建一个序列化类继承Serializer
			-2 在类中写要序列化的字段

简单使用

模型层

from django.db import models

# Create your models here.
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)
    publish_date = models.DateField(null=True)
    kind = models.IntegerField(choices=((0, ‘文学类‘), (1, ‘情感类‘)), default=1, null=True)
    publish = models.ForeignKey(to=‘Publish‘, to_field=‘nid‘, on_delete=models.CASCADE, null=True)
    authors = models.ManyToManyField(to=‘Author‘)

    def __str__(self):
        return self.name

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name

自定义序列化器

from rest_framework import serializers

class BookSerializer(serializers.Serializer):
    name = serializers.CharField()
    price = serializers.CharField()

视图层

# Create your views here.
from rest_framework.response import Response
from rest_framework.views import APIView

from app01 import models
from app01.app01serialier import BookSerializer

class Books(APIView):

    def get(self, request):
        response = {‘code‘: 100, ‘msg‘: ‘查询成功‘}
        books = models.Book.objects.all()
        # 如果序列化是多个,就要传入many=true,序列化一条可以不写
        bookser = BookSerializer(books, many=True)
        response[‘data‘] = bookser.data
        return Response(response)

序列化的高级用法

souce,指定数据来源

from rest_framework import serializers

class BookSerializer(serializers.Serializer):
    book_name = serializers.CharField(source=‘book‘)
    price = serializers.CharField()
    publish = serializers.CharField(source=‘publish.name‘)

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "code": 100,
    "msg": "查询成功",
    "data": [
        {
            "book_name": "红楼梦",
            "price": "14.00",
            "publish": "北方出版社"
        },
        {
            "book_name": "水浒传",
            "price": "19.00",
            "publish": "南方出版社"
        }
    ]
}

source,指定方法名

from rest_framework import serializers

class BookSerializer(serializers.Serializer):
    book_name = serializers.CharField(source=‘book‘)
    price = serializers.CharField()
    publish = serializers.CharField(source=‘publish.name‘)
    book_class = serializers.CharField(source=‘get_kind_display‘)

返回结果

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "code": 100,
    "msg": "查询成功",
    "data": [
        {
            "book_name": "红楼梦",
            "price": "14.00",
            "publish": "北方出版社",
            "book_class": "情感类"
        },
        {
            "book_name": "水浒传",
            "price": "19.00",
            "publish": "南方出版社",
            "book_class": "情感类"
        }
    ]
}

序列化中绑定方法

    publish_detail = serializers.SerializerMethodField()

    def get_publish_detail(self, obj):
        return {‘name‘: ‘obj.publish.name‘, ‘city‘: ‘obj.publish.city‘}
	-read_only:反序列化时,不传
	-write_only:序列化时,不显示

反序列化

instance 是我序列化的对象,data是要反序列化的数据,因此反序列化的时候要用关键字参数传值data = request.data

如果要使用反序列化必须要重写create方法

    def create(self, validated_data):
        ret = models.Book.objects.create(**validated_data)
        return ret
    def post(self,request):
        bookser = BookSerializer(data=request.data)
        if bookser.is_valid():
            # 检验通过的数据才会放在
            ret = bookser.create(bookser.validated_data)

根据表模型创建序列化器

只要在序列化函数中定义一个meta类,在类中的字段是固定给的

  • model 指定要绑定的模型表
  • field 指定要绑定的字段,__all__代表全部字段
  • exclude 代表要排除的字段
  • depth 存在连表的情况下,要把几个表中的数据返回,返回的数据时列表中所有的数据

序列化类


class BookSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.Book
        fields = (‘__all__‘)
        exclude = (‘name‘)
        depth = 1 # 表的数据没有控制,会把所有的数据都拿出来

视图层


class Books(APIView):

    def get(self, request):
        response = {‘code‘: 100, ‘msg‘: ‘查询成功‘}
        books = models.Book.objects.all()
        # 如果序列化是多个,就要传入many=true,序列化一条可以不写
        bookser = BookSerializer(books, many=True)
        response[‘data‘] = bookser.data
        return Response(response)
    def post(self,request):
        bookser = BookSerializer(data=request.data)
        if bookser.is_valid():
            bookser.save()

钩子函数

局部钩子使用validate__表名定义

全局钩子使用validata定义

def validate_name(self,value):

        print(value)
        raise exceptions.ValidationError(‘不能以sb开头‘)
        # if value.startswith(‘sb‘):
        #     raise ValidationError(‘不能以sb开头‘)
        # return value

    def validate(self,attrs):
        print(attrs)
        # if attrs.get(‘price‘)!=attrs.get(‘xx‘):
        #     raise exceptions.ValidationError(‘name和price相等,不正常‘)
        return attrs

代码折叠

<details>
  <summary>什么是iuap design</summary>
  iuap design 是用友网络FED团队开发的企业级应用前端集成解决方案。
</details>

<details>
  <summary>什么是tinper</summary>

`tinper`是开源前端技术平台。
</details>
什么是iuap design

iuap design 是用友网络FED团队开发的企业级应用前端集成解决方案。

原文地址:https://www.cnblogs.com/ruhai/p/11123784.html

时间: 2024-08-29 15:47:10

Django Restful Framework的相关文章

3- vue django restful framework 打造生鲜超市 - model设计和资源导入

3- vue django restful framework 打造生鲜超市 - model设计和资源导入 使用Python3.6与Django2.0.2(Django-rest-framework)以及前端vue开发的前后端分离的商城网站 项目支持支付宝支付(暂不支持微信支付),支持手机短信验证码注册, 支持第三方登录.集成了sentry错误监控系统. 本小节内容: model设计与资源引入 资源初始化 数据库设计,数据表结构 新建虚拟环境 mkvirtualenv -p=D:\softEnv

django restful framework 一对多方向更新数据库

目录 django restful framework 序列化 一 . 数据模型: models 二. 序列化: serializers 三, 视图: views 四, 路由: urls 五. 测试 : test django restful framework 序列化 案例: 一个网域domain可以绑定多台服务器主机assets, 但是一台服务器只能绑定一个网域. 数据模型之间关系适用于一对多. 一 . 数据模型: models 定义 assets 模型:apps/assets/models

Django Restful Framework【第三篇】认证、权限、限制访问频率

一.认证 认证请求头 views.py #!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.authentication import BaseAuthentication from rest_framework.permissions import

Django Restful Framework【第四篇】版本、解析器、序列化和请求数据验证

一.版本 程序也来越大时,可能通过版本不同做不同的处理 没用rest_framework之前,我们可以通过以下这样的方式去获取. class UserView(APIView): def get(self,request,*args,**kwargs): version = request.query_params.get('version') print(version) if version=='v1': #如果版本是v1 ret = { 'code':111, 'msg':'版本一的内容'

Django Restful Framework【第五篇】分页、视图、路由、渲染器

一.分页 试问如果当数据量特别大的时候,你是怎么解决分页的? 方式a.记录当前访问页数的数据id 方式b.最多显示120页等 方式c.只显示上一页,下一页,不让选择页码,对页码进行加密 1.基于limit offset 做分页 from rest_framework.pagination import LimitOffsetPagination urls.py urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^app01/(?P<v

vue+django+restful framework ForYou2.0

1.技术储备 项目环境搭建 vue环境搭建 nodejs cnpm 运行vue项目: cnpm install cnpm  run dev 前后端分离的优点: pc.移动端多端适用 SPA开发模式流行 前后端职责不清 开发效率,前后端相互等待 前端一直配合后端能力有限 后端开发语言与模板高度耦合,导致开发语言依赖严重 前后端分离缺点: 前后端学习成本增加 数据依赖导致文档重要性增加 前端工作量增加 SEO的难度增加 后端开发模式迁移增加成本 Vue基本概念 前端工程化 数据双向绑定 组件化开发

利用 Django REST framework 编写 RESTful API

利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framework 真乃一大神器,可以轻易的甚至自动化的搞定很多事情,比如: 自动生成符合 RESTful 规范的 API 支持 OPTION.HEAD.POST.GET.PATCH.PUT.DELETE 根据 Content-Type 来动态的返回数据类型(如 text.json) 生成 browserable

Getting Started with Django Rest Framework and AngularJS

转载自:http://blog.kevinastone.com/getting-started-with-django-rest-framework-and-angularjs.html A ReSTful API is becoming a standard component of any modern web application. The Django Rest Framework is powerful framework for developing ReST endpoints

Restful Framework 初识

目录 一.什么是RESTful 二.什么是API 三.RESTful API规范 四.基于Django实现API 五.基于Django Rest Framework框架实现 一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些