REST-framework快速构建API--初体验
一、快速上手
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--初体验的更多相关文章
- 5分钟APIG实战: 使用Rust语言快速构建API能力开放
序言:Rust语言简介 参与过C/C++大型项目的同学可能都经历过因为Null Pointer.Memory Leak等问题“被” 加班了不知道多少个晚上.别沮丧,你不是一个人,Mozilla Fir ...
- Hbase王国游记之:Hbase客户端API初体验
§历史回顾 2018年岁末,李大胖朦胧中上了开往Hbase王国的车,伴着一声长鸣,列出缓缓驶出站台,奔向无垠的广袤. (图片来自于网络) 如不熟悉剧情的,可观看文章: 五分钟轻松了解Hbase列式存储 ...
- net core 微服务 快速开发框架 Viper 初体验2020-10-17
1.Viper是什么? Viper 是.NET平台下的Anno微服务框架的一个示例项目.入门简单.安全.稳定.高可用.全平台可监控.底层通讯可以随意切换thrift grpc. 自带服务发现.调用链追 ...
- web api 初体验之 GET和POST传参
上一篇我们讲到了web api跨域的问题 它几乎是每一个用web api的人都需要去解决的问题,不然都没法测试.接下来会遇到的问题就是传参了.还是用js前台调用服务的方式. GET 方式 get方式传 ...
- web api 初体验 解决js调用跨域问题
跨域界定 常见跨域: 同IP不同端口: http:IP:8001/api/user http:IP:8002/api/user 不同IP不同端口: http://172.28.20.100:8 ...
- Kong Api 初体验
请查看原文: https://www.fangzhipeng.com/nginx/kong/2016/07/11/kong-api-gateway/ Kong是一个可扩展的开源API层(也称为API网 ...
- Django Rest Framework 教程及API向导
Django Rest Framework 教程及API向导. 一.请求(Request)REST_FRAMEWORK 中的 Request 扩展了标准的HttpRequest,为 REST_FRAM ...
- .NET Core初体验 在window上构建第一个app
ASP.NET Core 是一个跨平台,高性能的开源框架,用于构建现代化的,基于云的互联网应用程序.使用 ASP.NET Core ,您可以: 构建Web应用程序和服务,IoT应用程序和移动后端. 在 ...
- gulp快速入门&初体验
前言 一句话先 gulp 是一个可以简单和自动化"管理"前端文件的构建工具 先说我以前的主要工作,我主要是做游戏服务端的,用c++/python,所以我对东西的概念理解难免要套到自 ...
- 快速构建第三方api应用
1.使用框架和扩展 详细请看composer.json "php": "^7.1.3", "laravel-admin-ext/config" ...
随机推荐
- Angular 服务的简单使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- DLL导出类避免地狱问题的完美解决方案
DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类, ...
- 1.1环境的准备(一)之Python解释器的安装
目录: 1.Python-解释器的下载 2.Python-解释器的安装 3.Python-解释器的测试 4.Python的环境变量的配置 (一)Python解释器的安装: 1.官网:https://w ...
- sed和awk学习整理
Awk和Sed的基本使用 可以用大至相同的方式调用sed 和awk .命令行讲法是:command [options] script filename几乎和所有的unlx程序一样,sed和awk都可以 ...
- spark任务调度和资源分配
Spark调度模式 FIFO和FAIR Spark中的调度模式主要有两种:FIFO和FAIR. 默认情况下Spark的调度模式是FIFO(先进先出),谁先提交谁先执行,后面的任务需要等待 ...
- app的描述-软件的描述
app的描述=需求文档+接口文档+程序架构+工程结构. 程序架构:类结构图: 需求文档:业务逻辑-->时序图.
- BZOJ4269:再见Xor(线性基)
Description 给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值. Input 第一行一个正整数N. 接下来一行N个非负整数. ...
- 天地图api地址
天地图地址 http://lbs.tianditu.com/api-new/examples.html 参考资料 http://lbs.tianditu.com/api-new/class.html
- Eclipse Mars 2安装Drools6.4插件(Drools and jBPM tools)时无法安装JBoss Runtime Drools Detector
在eclipse上本地安装Drools6.4Final的时候出现两个组件无法正常安装的情况,具体组件如下: 具体的提示信息为: Cannot complete the install because ...
- oracle查询2G以上的表
SELECT a.*, b.comments FROM (SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, ...