一、快速上手

1、环境准备

安装restframework,注册app

pip install djangorestframework
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、url

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^publish/', views.PublishView.as_view()),
]

3、models

# -*- coding: utf-8 -*-
from __future__ import unicode_literals from django.db import models # Create your models here.
from django.db import models # Create your models here. class Book(models.Model):
title=models.CharField(max_length=32)
price=models.IntegerField()
pub_date=models.DateField()
publish=models.ForeignKey("Publish")
authors=models.ManyToManyField("Author")
def __str__(self):
return self.title class Publish(models.Model):
name=models.CharField(max_length=32)
email=models.EmailField()
def __str__(self):
return self.name class Author(models.Model):
name=models.CharField(max_length=32)
age=models.IntegerField()
def __str__(self):
return self.name

4、views

基于CBV方式

# -*- coding: utf-8 -*-
from __future__ import unicode_literals from django.shortcuts import render,HttpResponse # Create your views here.
from .models import Publish
from rest_framework.views import APIView class PublishView(APIView):
def get(self,request): #序列化方式4rest_framework
from rest_framework.response import Response
publish_list = Publish.objects.all()
ps = PublishSerializers(publish_list, many=True)
return Response(ps.data) def post(self,request):
return HttpResponse('POST')

5、测试

二、结果序列化

API返回结果的形式,json是非常流行的。但是我们在序列化结果时,有多种方式,每种方式实现的方式不同。

1、原生json方式

import json
publish_list = list(Publish.objects.all().values())
return HttpResponse(json.dumps(publish_list))

 使用json方式对结果进行强转,先把结果强转成列表的方式,然后通过json的dumps方式对结果进行格式化。

注意:

这种方式实现最简单,也可以自定制需要返回的字段,通过在values中填写自己需要的字段即可。

2、model_to_dict方法

#序列化方式2
# from django.forms.models import model_to_dict
# publish_list = Publish.objects.all()
# data = []
# for obj in publish_list:
# data.append(model_to_dict(obj))
# return HttpResponse(data)

  通过models自带的model_to_dict方法直接把obj对象转换成字典的形式,然后返回。缺点:需要把每个对象再次进行处理。

3、django自带的serializers方法

#序列化方式3
# from django.core import serializers
# publish_list = Publish.objects.all()
# data = serializers.serialize("json", publish_list)
# return HttpResponse(data)

  

三、基于REST-framework序列化

from rest_framework import serializers
class PublishSerializers(serializers.Serializer):
name=serializers.CharField(max_length=32)
email=serializers.CharField() from rest_framework.views import APIView
视图函数继承APIView方法
#序列化方式4rest_framework
from rest_framework.response import Response
publish_list = Publish.objects.all()
ps = PublishSerializers(publish_list, many=True)
return Response(ps.data)

  

既然有了前面三种方法,为什么这里还要用restframework的第四种方法呢?原因如下:

a、对于表结构复杂的情况,前面三种没有涉及到,需要我们自己去通过写逻辑代码实现;

b、对于我们需要的返回表结构中字段的结果,定制也是个问题,比如,我们的api只需要返回指定的几个字段;

c、对于我们后面对资源的操作,比如POST动作,需要对结果进行保存,是不是我们每次都需要自己写create方法去保存结果呢?

d、对于错误的处理;

等等.....诸如此类的需要考虑的问题,rest-framework都帮我们写好了逻辑,只需要我们去调用即可。

对于复杂表结构

from rest_framework import serializers

class BookSerializers(serializers.Serializer):
title=serializers.CharField(max_length=32)
price=serializers.IntegerField()
pub_date=serializers.DateField()
#一对多,可以通过source指定列名,默认为str或unicode方法显示的
publish=serializers.CharField(source="publish.name")
#对于多对多我们可以自定义get_field方法,将object添加进去
authors=serializers.SerializerMethodField()
def get_authors(self,obj):
temp=[]
for author in obj.authors.all():
temp.append(author.name)
return temp

 

class BookViewSet(APIView):

    def get(self,request,*args,**kwargs):
book_list=Book.objects.all() bs=BookSerializers(book_list,many=True)
return Response(bs.data)

  注意:这里的many=True,表示对queryset进行操作,默认为对model对象进行操作。

四、使用ModelSerializer

class BookSerializers(serializers.ModelSerializer):
class Meta:
model=Book
fields="__all__"
depth=1

  
保存数据:

def post(self,request,*args,**kwargs):

        bs=BookSerializers(data=request.data,many=False)
if bs.is_valid():
# print(bs.validated_data)
bs.save()
return Response(bs.data)
else:
return HttpResponse(bs.errors)

  通过ModelSerializer方法,类似ModelForm方法,我们可以通过Meta类直接指定Model、fields,就能满足我们的需求。操作哪个表,提交哪些字段。save方法其实后端是调用的create方法,将我们提交的数据进行保存。

注意:

在BookSerializers里面,我们同样可以自定义返回多对多或一对多字段内容;

class BookSerializers(serializers.ModelSerializer):
class Meta:
model=Book
fields="__all__"
depth=1
publish=serializers.CharField(source="publish.name")
authors=serializers.SerializerMethodField()
def get_authors(self,obj):
temp=[]
for author in obj.authors.all():
temp.append(author.name)
return temp

  但是这里如果使用ModelSerializer方法,使用save方法时,ModelSerializer默认自带的create方法不支持多对多的保存,需要我们重载create方法:

class BookSerializers(serializers.ModelSerializer):

      class Meta:
model=Book
fields="__all__"
# exclude = ['authors',]
# depth=1 def create(self, validated_data): authors = validated_data.pop('authors')
obj = Book.objects.create(**validated_data)
obj.authors.add(*authors)
return obj

  

五、单条数据操作

针对单条数据进行操作,比如books/1(GET/PUT/DELETE)

class BookDetailViewSet(APIView):

    def get(self,request,pk):
book_obj=Book.objects.filter(pk=pk).first()
bs=BookSerializers(book_obj)
return Response(bs.data) def put(self,request,pk):
book_obj=c
bs=BookSerializers(book_obj,data=request.data)
if bs.is_valid():
bs.save()
return Response(bs.data)
else:
return HttpResponse(bs.errors) def delete(self,request,pk):
Book.objects.filter(pk=pk).delete()
return Response()

  

注意:

put进行更新数据时,需要把单条数据的每个字段写全,即使之前已经是完整的一条记录,否则会报错。

  

六、超链接API

class BookSerializers(serializers.ModelSerializer):
publish= serializers.HyperlinkedIdentityField(
view_name='publish_detail',
lookup_field="publish_id",
lookup_url_kwarg="pk")
class Meta:
model=Book
fields="__all__"
#depth=1

  

urls

urlpatterns = [
url(r'^books/$', views.BookViewSet.as_view(),name="book_list"),
url(r'^books/(?P<pk>\d+)$', views.BookDetailViewSet.as_view(),name="book_detail"),
url(r'^publishers/$', views.PublishViewSet.as_view(),name="publish_list"),
url(r'^publishers/(?P<pk>\d+)$', views.PublishDetailViewSet.as_view(),name="publish_detail"),
]

  

注意:

1、反向解析,通过name进行命名,这个代表前面的URL,不管pk怎么变化都可以引用;

2、view_name为反向解析的name,lookup_field为对应的哪个字段,这里的pk对应的是Model里面的id字段;

3、lookup_url_kwarg是命名url里面的分组关键字;

4、需要在views函数里面新增一个context={'request':request}

class BookView(APIView):
def get(self,request):
book_list=Book.objects.all()
bs=BookModelSerializers(book_list,many=True,context={'request': request})
return Response(bs.data)
def post(self,request):
# post请求的数据
bs=BookModelSerializers(data=request.data)
if bs.is_valid():
print(bs.validated_data)
bs.save()# create方法
return Response(bs.data)
else:
return Response(bs.errors)

注意:这里有一个问题,使用超链接post数据的时候,会有一个报错:

需要去掉超链接的配置才能POST数据,这里还没找到解决办法。

REST-framework快速构建API--初体验的更多相关文章

  1. 5分钟APIG实战: 使用Rust语言快速构建API能力开放

    序言:Rust语言简介 参与过C/C++大型项目的同学可能都经历过因为Null Pointer.Memory Leak等问题“被” 加班了不知道多少个晚上.别沮丧,你不是一个人,Mozilla Fir ...

  2. Hbase王国游记之:Hbase客户端API初体验

    §历史回顾 2018年岁末,李大胖朦胧中上了开往Hbase王国的车,伴着一声长鸣,列出缓缓驶出站台,奔向无垠的广袤. (图片来自于网络) 如不熟悉剧情的,可观看文章: 五分钟轻松了解Hbase列式存储 ...

  3. net core 微服务 快速开发框架 Viper 初体验2020-10-17

    1.Viper是什么? Viper 是.NET平台下的Anno微服务框架的一个示例项目.入门简单.安全.稳定.高可用.全平台可监控.底层通讯可以随意切换thrift grpc. 自带服务发现.调用链追 ...

  4. web api 初体验之 GET和POST传参

    上一篇我们讲到了web api跨域的问题 它几乎是每一个用web api的人都需要去解决的问题,不然都没法测试.接下来会遇到的问题就是传参了.还是用js前台调用服务的方式. GET 方式 get方式传 ...

  5. web api 初体验 解决js调用跨域问题

    跨域界定 常见跨域: 同IP不同端口: http:IP:8001/api/user     http:IP:8002/api/user 不同IP不同端口: http://172.28.20.100:8 ...

  6. Kong Api 初体验

    请查看原文: https://www.fangzhipeng.com/nginx/kong/2016/07/11/kong-api-gateway/ Kong是一个可扩展的开源API层(也称为API网 ...

  7. Django Rest Framework 教程及API向导

    Django Rest Framework 教程及API向导. 一.请求(Request)REST_FRAMEWORK 中的 Request 扩展了标准的HttpRequest,为 REST_FRAM ...

  8. .NET Core初体验 在window上构建第一个app

    ASP.NET Core 是一个跨平台,高性能的开源框架,用于构建现代化的,基于云的互联网应用程序.使用 ASP.NET Core ,您可以: 构建Web应用程序和服务,IoT应用程序和移动后端. 在 ...

  9. gulp快速入门&初体验

    前言 一句话先 gulp 是一个可以简单和自动化"管理"前端文件的构建工具 先说我以前的主要工作,我主要是做游戏服务端的,用c++/python,所以我对东西的概念理解难免要套到自 ...

  10. 快速构建第三方api应用

    1.使用框架和扩展 详细请看composer.json "php": "^7.1.3", "laravel-admin-ext/config" ...

随机推荐

  1. python2编码的问题

    1,python2的默认编码是ascii码. 2,python2中有2中数据模型来支持字符串这种数据类型,分别为str和unicode. 3,uncode转换为其他编码是encode,其他编码转换成u ...

  2. scaffold-dbcontext 命令使用说明

    工具的scaffold-dbcontext(数据库上下文脚手架)指令来生成models和context. 指令详细介绍: Scaffold-DbContext [-Connection] <St ...

  3. win Server 2008 笔记

    1.开启tsmmc 远程登录连接 需要在入站规则中启用一下规则 远程管理(RPC-EPMAP) 远程管理(RPC) 远程管理(RPCNP-IN) 远程管理(TCP-IN) 远程管理 - RemoteF ...

  4. python常用内置模块

    #持续更新 #在使用内置模块的时候需要导入,例如import abc,则导入abc模块,当然模块也可以自己写,相当于一个类,后面放到类里说,这个因为环境闲置,有些无法执行,只能理解了 #os系统操作 ...

  5. 关于ORA-00257: archiver error. Connect internal only, until freed 错误处理方法

    产生原因:出现ORA-00257错误(空间不足错误),通过查找资料,绝大部分说这是由于归档日志太多,占用了全部的硬盘剩余空间导致的,通过简单删除日志或加大存储空间就能够解决 解决办法:(亲测有效) 1 ...

  6. Alpha冲刺报告(4/12)(麻瓜制造者)

    今日完成的情况 江郑: 今天对数据库的需求部分进行了完善 邓弘立: 完成了首页界面UI 刘双玉: 基本完成商品信息发布接口 汪志彬: 尝试UI的设计 符天愉: 将登录接口部署到服务器上,结果Linux ...

  7. C# MVC 使用 CKEditor图片上传 提示“不正确的服务器响应”

    重点:看一下你使用的CKEditor版本 过程: 后台需要一款富文本编辑器.经过挑选后,最后选择了FCKEditor 的升级版 CKEditor .在官网下载了4.10.1版本. 经过一番配置后,富文 ...

  8. Oracle Spatial中SDO_Geometry说明

    Oracle Spatial中SDO_Geometry说明 在ArcGIS中通过SDE存储空间数据到Oracle中有多种存储方式,分别有:二进制Long Raw .ESRI的ST_Geometry以及 ...

  9. JFreeChart框架中生成饼状图上怎样显示数据 [问题点数:40分,结帖人GreenLawn]

    我用JFreeChart框架生成饼状图,但想把数据信息在饼图上显示,是在饼图内部(即圆内)显示!怎样实现啊??  去掉lablepieplot.setLabelGenerator(null);去掉线p ...

  10. 【洛谷】【单调栈】P1823 音乐会的等待

    [题目描述:] N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见 ...