DRF笔记一

本文介绍了RESTful规范,包括根据HTTP方法进行不同的操作、使用HTTPS协议、资源的命名与版本控制、过滤、状态码和错误处理。同时探讨了Django Rest Framework的应用,前后端分离的优势,Django中的CBV与FBV区别,以及中间件的使用,特别是CSRF认证的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

restful规范(建议)

1、根据method不同做不同的操作,示例:

  • GET :从服务器取出资源(一项或多项)
  • POST :在服务器新建一个资源
  • PUT :在服务器更新资源(客户端提供改变后的完整资源)
  • PATCH :在服务器更新资源(客户端提供改变的属性)
  • DELETE :从服务器删除资源

基于FBV实现:

#url.py
from django.urls import path
from app01 import views

urlpatterns = [
    path('order/', views.order),
    path('order1/', views.OrderView.as_view()),
]

#view.py
@csrf_exempt
def order(request):
    if request.method == 'GET':
        return HttpResponse('获取订单')
    elif request.method == 'POST':
        return HttpResponse('创建订单')
    elif request.method == 'PUT':
        return HttpResponse('更新订单')
    elif request.method == 'DELETE':
        return HttpResponse('删除订单')
    else:
        return HttpResponse('错误的请求方式')

基于CBV实现:

from django.urls import path
from app01 import views

urlpatterns = [
    path('order/', views.order),
    path('order1/', views.OrderView.as_view()),
]

@method_decorator(csrf_exempt, name='dispatch')
class OrderView(View):
    def get(self, request, *args, **kwargs):
        return HttpResponse('获取订单')

    def post(self, request, *args, **kwargs):
        return HttpResponse('创建订单')

    def put(self, request, *args, **kwargs):
        return HttpResponse('更新订单')

    def delete(self, request, *args, **kwargs):
        return HttpResponse('删除订单')

2、API与用户的通信协议,总是使用HTTPs协议

3、域名

  • 子域名方式:(域名不同,由于浏览器存在同源策略,需解决跨域问题)

    https://www.example.com (用户访问的网址,前端展示地址)

    https://api.example.com 尽量将API部署在专用域名(会存在跨域问题)

  • URL方式:(域名相同,不存在跨域问题,使用简单)

    https://www.example.com (用户访问的网址,前端展示地址)

    https://www.example.org/api/ API很简单

4、版本

  • URL,如:https://api.example.com/v1/或者https://www.example.org/api/v1
  • 请求头 跨域时,引发发送多次请求

5、路径,视网络上任何东西都是资源,均使用名词表示(可复数)

  • https://api.example.com/v1/zoos
  • https://api.example.com/v1/animals
  • https://api.example.com/v1/employees

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、状态吗加code

200系列:成功

300系列:重定向

400系列:客户端错误

500系列:服务器错误

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

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

如果规定的状态吗无法满足开发要求时,可以使用code加以修饰

class OrderView(View):
    def get(self, request, *args, **kwargs):
        ret = {
            'code': 1000,
            'msg': 'xxxx'
        }
        return HttpResponse(json.dumps(ret), status=201)

8、错误处理,状态码是4xx时,应返回错误信息,建议error当做key。

{
    error: "Invalid API key"
}

9、返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。

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

例如:

GET /order/:获取所有订单信息
GET /order/1/:获取单个订单信息
POST /order/:返回新生成的资源对象
PUT /order/1:返回完整的资源对象
PATCH /order/1:返回完整的资源对象
DELETE /order/1:返回一个空文档

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"
}}

例如:

/order/

[
    {
        id:1,
        name:'苹果'
        url:https://www.example.org/api/order/1/
    },
    {
        id:1,
        name:'苹果'
        url:https://www.example.org/api/order/2/
    }
]

django rest framework框架

前后端分离好处?

无论app还是pc端都可以用一套数据源(后端api接口),节省成本;

代码逻辑简单(如果原先只是pc端,现在要适应app,只需前端改代码);

django中CBV与FBV差别

CBV:class base views 就是在视图里使用类处理请求,

基于反射实现,根据请求方式不同,执行不同方法。

原理:

​ a、路由 -> as_view()方法 -> view方法 -> dispatch方法(反射执行其他方法:GET/POST/PUT/DELETE)

FBV:function base views 就是在视图里使用函数处理请求

view层代码:

#FBV
def users(request):
	if request.method == 'GET':
        user_list = ['madl', 'josn']
        return HttpResponse(json.dumps(user_list))
    if request.method == 'POSt':
        return HttpResponse('POST')
  
# CBV
class Studentsview(View):

    def get(self, request, *args, **kwargs):
        return HttpResponse('GET')

    def post(self, request, *args, **kwargs):
        return HttpResponse('POST')

    def put(self, request, *args, **kwargs):
        return HttpResponse('PUT')

    def delete(self, request, *args, **kwargs):
        return HttpResponse('DELETE')

url层代码:

from django.urls import path
from app01 import views

urlpatterns = [
    # path('admin/', admin.site.urls),
    path('users/', views.users),
    path('students/', views.Studentsview.as_view()),
]

当我们使用CBV方式时,首先要注意urls.py文件中要写成“类名.as_view()”方式映射,其次在类中我们定义的get/post方法这些方法的名字不是我们自己定义的,而是按照固定样式,View类中支持以下方法

'get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'

django中间件回顾

1、django中间件(最多五个函数)

  • process_request

  • process_view

  • process_response

  • process_exception

  • process_render_template

    执行顺序:

    请求过来,先执行process_request,然后路由匹配,执行process_view,寻找对应的视图函数,最后执行process_response,如果中途程序出现异常执行process_exception,如果视图函数中返回的render方法,渲染模板,那么process_render_template就会执行。

2、使用中间件做过什么?

  • 权限

  • 用户登录验证

  • csrf_token ,django的csrf是如何实现的?

    通过process_view方法实现的:

    ​ 先检查视图函数是否被@csrf_exempt装饰(免除csrf认证),如果有跳过csrf认证,如果没有则去请求体或者cookie中获取token,验证token,正确则通过,错误则抛出csrf异常。

csrf_token原理:

​ 当用post提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会报错。这也是之前我们一直将其注释的原因,在django内部支持生成这个随机字符串。

3、处理django中csrf_token认证问题

  • 情况一:

全站使用csrf认证,但有个别函数不需要csrf认证,使用装饰器@csrf_exempt

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware', # 表示全站使用csrf认证
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


from django.views.decorators.csrf import csrf_exempt
# 加这个装饰器表示该函数免除csrf认证
@csrf_exempt
def users(request):
    user_list = ['madl', 'josn']
    return HttpResponse(json.dumps(user_list))
  • 情况二:

全站都不需要csrf认证,但有个别函数需要csrf认证,使用装饰器@csrf_protect

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware', # 表示全站都不使用csrf认证
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


from django.views.decorators.csrf import csrf_exempt, csrf_protect
#该函数需要csrf认证
@csrf_protect
def users(request):
    user_list = ['madl', 'josn']
    return HttpResponse(json.dumps(user_list))
  • 情况三:(一般用于前后端不分离情况)

在form表单里面需要添加{%csrf_token%},这样当你查看页面源码的时候,可以看到form中有一个input是隐藏的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UVINeLNi-1583204767182)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1582790901103.png)]

总结原理:当用户访问login页面的时候,会生成一个csrf的随机字符串,,并且cookie中也存放了这个随机字符串,当用户再次提交数据的时候会带着这个随机字符串提交,如果没有这个随机字符串则无法提交成功

  • 情况四:

    使用Django提供的 Django-cors-headers 来处理跨域,安装并根据文档配置即可。

CBV小知识点

如果想要在CBV中的方法免于csrf认证,需要使用@method_decorator()装饰器,并将csrf_exempt或者csrf_protect作为参数传入。

注意:@method_decorator()装饰器必须使用在dispatch方法中,单独对类中的某个方法使用无效。

from django.shortcuts import render, HttpResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator

# 方式一:
class Workerview(View):

    # 免于csrf认证
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(Workerview, self).dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return HttpResponse('GET')

    def post(self, request, *args, **kwargs):
        return HttpResponse('POST')

    def put(self, request, *args, **kwargs):
        return HttpResponse('PUT')

    def delete(self, request, *args, **kwargs):
        return HttpResponse('DELETE')
        
 
 # 方式二:
@method_decorator(csrf_exempt, name='dispatch')      
class Workerview(View):

    def get(self, request, *args, **kwargs):
        return HttpResponse('GET')

    def post(self, request, *args, **kwargs):
        return HttpResponse('POST')

    def put(self, request, *args, **kwargs):
        return HttpResponse('PUT')

    def delete(self, request, *args, **kwargs):
        return HttpResponse('DELETE')

总结

CBV

  • 本质:基于反射实现,根据请求方式不同,执行不同方法。
  • 流程:路由——》as_view函数——》view函数——》dispatch(反射)
  • 取消csrf认证(装饰器要加到dispatch方法上且使用method_decorator装饰)

csrf

  • 基于中间件process_view方法
  • 装饰器给单独函数进行设置(认证或无需认证)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值