Django高级进阶[DRF](3. 简化

请求和响应

请求对象(Request objects)拓展了Django自带的HttpRequest
  • REST框架引入了一个扩展了常规HttpRequest的Request对象,并提供了更灵活的请求解析。Request对象的核心功能是request.data属性,它与request.POST类似,但对于使用Web API更为有用
request.POST
  • 只处理表单数据 只适用于'POST'方法
request.data
  • 处理任意数据 适用于'POST','PUT'和'PATCH'方法

响应对象(Response objects)

  • REST框架还引入了一个Response对象,这是一种获取未渲染(unrendered)内容的TemplateResponse类型,并使用内容协商来确定返回给客户端的正确内容类型

return Response(data)

  • 渲染成客户端请求的内容类型。

状态码(Status codes)

  • 在你的视图(views)中使用纯数字的HTTP 状态码并不总是那么容易被理解。而且如果错误代码出错,很容易被忽略。REST框架为status模块中的每个状态代码(如HTTP_400_BAD_REQUEST)提供更明确的标识符。使用它们来代替纯数字的HTTP状态码是个很好的主意。

包装(wrapping)API视图

  • REST框架提供了两个可用于编写API视图的包装器(wrappers)
    1. 用于基于函数视图的@api_view装饰器。
    1. 用于基于类视图的APIView类。
  • 这些包装器提供了一些功能,例如确保你在视图中接收到Request实例,并将上下文添加到Response,以便可以执行内容协商。

  • 包装器还提供了诸如在适当时候返回405 Method Not Allowed响应,并处理在使用格式错误的输入来访问request.data时发生的任何ParseError异常。


应用

导入模块
from .models import Publisher
from rest_framework.decorators import api_view
from app01 import serializers
from rest_framework.response import Response

编写视图

GET
from .models import Publisher
from rest_framework.decorators import api_view
from app01 import serializers
from rest_framework.response import Response

# 列表里面的参数是被允许的操作,比如只有GET/POST请求,如果不是get或者post会报405--->405 Method Not Allowed
@api_view(['GET', 'POST'])
def publisher_list(request):
    """
    列出所有出版社,get
    或者创建一个新的出版社 post
    """
    if request.method == 'GET':
        # 所有的出版社
        queryset = Publisher.objects.all()
        # 把所有从数据库取出来的出版社信息数据进行序列化
        s = serializers.PublisherSerializer(queryset, many=True)
        return Response(s.data)

获取、更新或者删除一个(单个)出版社信息

GET

# GET 获取出版社 
@api_view(['GET', 'PUT', 'DELETE'])
def publisher_detail(request, pk):
try:
    # 从数据库里面找你要找的pk
    publisher = Publisher.objects.get(pk=pk)
    except Publisher.DoesNotExist: # 如果找不到浏览器传来的pk对应的数据,返回404
    return Response(status=status.HTTP_404_NOT_FOUND)

if request.method == 'GET':
    # 从数据库里面取出来的publisher进行序列化
    s = serializers.PublisherSerializer(publisher)
    return Response(s.data)

POST

if request.method == 'PUT':
    # publisher使我们查出来的出版社信息  request.data是客户端传过来的
    s = serializers.PublisherSerializer(publisher, data=request.data)
    if s.is_valid():# 如果数据没有问题
        s.save()
        return Response(s.data)
    else:
        return Response(status=status.HTTP_204_NO_CONTENT)

DELETE

if request.method == 'DELETE':
    publisher.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)


给我们的网址添加可选的格式后缀

  • 为了充分利用我们的响应不再与单一内容类型连接,我们可以为API路径添加对格式后缀的支持。使用格式后缀给我们明确指定了给定格式的URL,这意味着我们的API将能够处理诸如
  • http:/\/example.com/api/items/4.json 之类的URL。

设置路由

url(r'^publishers/(?P<pk>[0-9]+)/$', views.publisher_detail)
刷新浏览器
创建一个账号
  • 接下来我们可以通过两种方式访问
方式一: httpie
pip install httpie
  • 然后在命令行访问
方式二:(调出登录)
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))


基于类的视图(CBV)

导入模块
from rest_framework.views import APIView

GET

from .models import Publisher
from app01 import serializers
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView

class PublisherList(APIView):
    """列出所有的出版,get或者创建一个新的出版社post"""
    def get(self, request, format=None):
        queryset = Publisher.objects.all() # 查询出所有出版社
        s = serializers.PublisherSerializer(queryset, many=True)
        return Response(s.data, status=status.HTTP_200_OK)

POST

def post(self,request,format=None):
    s = serializers.PublisherSerializer(data=request.data)
    if s.is_valid():
        s.save()
        return Response(s.data,status=status.HTTP_201_CREATED)
    else:
        return Response(s.errors,status=status.HTTP_400_BAD_REQUEST)

具体的某一个出版社CBV

class PublisherDetail(APIView):
"""具体的某一个出版社  查看.修改.删除的视图"""

# 需要先尝试的从数据库查到 pk对应的数据,如果没有返回404
def get_object(self, pk):
    try:
        return Publisher.objects.get(pk=pk)
    except Publisher.DoesNotExist:
        raise Http404 # 需要先导入 from django.http import Http404

GET 获取出版社信息(单个)

def get(self, request, pk, format=None):
    publisher = self.get_object(pk)
    s = serializers.PublisherSerializer(publisher)
    return Response(s.data, status=status.HTTP_200_OK)

PUT 修改出版社信息(单个)

def put(self, request, pk, format=None):
    publisher = self.get_object(pk)
    s = serializers.PublisherSerializer(publisher, data=request.data)
    if s.is_valid():
        s.save()
        return Response(s.data)
    else:
        Response(s.errors, status=status.HTTP_400_BAD_REQUEST)

DELETE  删除出版社信息(单个)

def delete(self, request, pk, format=None):
    """删除出版社信息"""
    publisher = self.get_object(pk)
    publisher.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

修改url

url(r'^publishers/$', views.PublisherList.as_view()),
url(r'^publishers/(?P<pk>[0-9]+)/$', views.PublisherDetail.as_view()),


使用混合(mixins)

  • 使用基于类视图的最大优势之一是它可以轻松地创建可复用的行为。
  • 到目前为止,我们使用的创建/获取/更新/删除操作和我们创建的任何基于模型的API视图非常相似。这些常见的行为是在REST框架的mixin类中实现的。

导入模块

from rest_framework import mixins
from rest_framework import generics

编写视图

from rest_framework import mixins
from rest_framework import generics

class PublisherList(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):

    queryset = Publisher.objects.all()
    serializers_class = serializers.PublisherSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

class PublisherDetail(mixins.RetrieveModelMixin,
    mixins.UpdateModelMixin,
    mixins.DestroyModelMixin,
    generics.GenericAPIView):

    queryset = Publisher.objects.all()
    serializer_class = serializers.PublisherSerializer

def get(self, request, *args, **kwargs):
    return self.retrieve(request, *args, **kwargs)

def put(self, request, *args, **kwargs):
    return self.update(request, *args, **kwargs)

def delete(self, request, *args, **kwargs):
    return self.destroy(request, *args, **kwargs)
  • 刷新浏览器


改进混合视图
class PublisherList(generics.ListCreateAPIView):
    queryset = Publisher.objects.all()
    serializer_class = serializers.PublisherSerializer

class PublisherDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Publisher.objects.all()
    serializer_class = serializers.PublisherSerializer
  • 刷新浏览器

  • 此时我们观察,代码已经精简至3行
  • 官方文档一句话说的非常好:仅仅只需要很少的几行代码,就可以完成非常清晰,简洁,地道的Django

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 绘画不要忘初心,相信每位艺术生对人体模特都不陌生。行外人可能会有玩味儿的心,但请不要忘记了尊重。属于艺术生的模特他...
    子曰悟语阅读 418评论 0 1
  • 隐私协议 欢迎您使用我们提供的服务,本隐私协议旨在协助您了解您在使用我们提供的服务的过程中,我们将会收集哪些信息,...
    waso_3e75阅读 559评论 0 0
  • Celery 是一个简单、灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具。它是一个专注...
    茶客furu声阅读 3,648评论 0 6