dangjo—RESTFUL API设计
1.自定制 restful api接口
# http://127.0.0.1:8000/api/servers.html GET: 获取服务器列表
# http://127.0.0.1:8000/api/servers.html POST: 创建服务器
# http://127.0.0.1:8000/api/servers/1.html GET: 获取单条信息
# http://127.0.0.1:8000/api/servers/1.html DELETE: 删除单条信息
# http://127.0.0.1:8000/api/servers/1.html PUT: 更新
#多个
def servers(request):
if request.method == 'GET':
v = models.Server.objects.values('id','hostname')
server_list = list(v)
return JsonResponse(server_list,safe=False)
elif request.method == 'POST':
# request.POST.get('...')
# models.Server.objects.create(。。。。、)
return JsonResponse(status=201)
#单个
def servers_detail(request,nid):
if request.method == 'GET':
obj = models.Server.objects.filter(id=nid).first()
return HttpResponse('...')
elif request.method == "DELETE":
models.Server.objects.filter(id=nid).delete()
return HttpResponse()
elif request.method == 'PUT':
request.body
models.Server.objects.filter(id=nid).update()
2. 什么是REST
- REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
- REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态
- REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
- 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
- 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)
设计参考:http://www.ruanyifeng.com/blog/2014/05/restful_api.html
3. 目前如何实现 REST API ?
按照规则,根据不同的请求方式做出不同的处理,并且返回内容以及相应状态码
4. 什么是 Django REST framework?
Django REST framework是一个基于Django开发的app,用于快速搭建REST API。
安装
pip3 install djangorestframework
a.快速使用
INSTALLED_APPS = [ ... 'rest_framework', ]
1 from rest_framework import routers 2 from . import views 3 4 5 router = routers.DefaultRouter() 6 router.register(r'users', views.UserInfoViewSet) 7 8 urlpatterns = [ 9 url(r'^', include(router.urls)), 10 ]
1 from rest_framework import viewsets 2 from . import models 3 from . import serializers 4 5 # ########### 1. 基本处理方式 ########### 6 7 class UserInfoViewSet(viewsets.ModelViewSet): 8 """ 9 API endpoint that allows users to be viewed or edited. 10 """ 11 queryset = models.UserInfo.objects.all().order_by('-id') 12 serializer_class = serializers.UserInfoSerializer
from rest_framework import serializers from . import models class UserInfoSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = models.UserInfo # fields = ('id', 'username', 'pwd','ug') # fields = '__all__' exclude = ('ug',) depth = 1 # 0<=depth<=10
PS:最终访问的路劲
[GET] http://127.0.0.1:8000/api/users/ [POST] http://127.0.0.1:8000/api/users/ [GET] http://127.0.0.1:8000/api/users/7/ [PUT] http://127.0.0.1:8000/api/users/7/ [DELETE] http://127.0.0.1:8000/api/users/7/
知识点:
JsonResponse(数据,safe=False)#非字典类型的数据,无法输出,需要添加safe=False
b.基于CBV
from django.conf.urls import url,include from django.contrib import admin from . import views urlpatterns = [ url(r'^users/$', views.UserList.as_view()), url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()), ]
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import JSONParser from . import models from . import serializers class UserList(APIView): def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all() serializer = serializers.MySerializer(instance=user_list, many=True) return Response(serializer.data) def post(self, request, *args, **kwargs): data = JSONParser().parse(request) serializer = serializers.MySerializer(data=data) if serializer.is_valid(): # print(serializer.data) # print(serializer.errors) # print(serializer.validated_data) # 如果有instance,则执行update方法;否则,执行create serializer.save() return Response(serializer.data, status=201) return Response(serializer.errors, status=400) class UserDetail(APIView): def get(self, request, *args, **kwargs): obj = models.UserInfo.objects.filter(pk=kwargs.get('pk')).first() serializer = serializers.MySerializer(obj) return Response(serializer.data) def delete(self, request, *args, **kwargs): obj = models.UserInfo.objects.filter(pk=kwargs.get('pk')).first() obj.delete() return Response(status=204) def put(self, request, *args, **kwargs): data = JSONParser().parse(request) obj = models.UserInfo.objects.filter(pk=kwargs.get('pk')).first() serializer = serializers.MySerializer(obj, data=data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=400)
from rest_framework import serializers from rest_framework.exceptions import ValidationError from . import models class MySerializer(serializers.Serializer): id = serializers.IntegerField(read_only=True) username = serializers.CharField(required=False, allow_blank=True, max_length=100) pwd = serializers.CharField() def validate_username(self, value): if value == '中国': raise ValidationError('用户名中存在敏感字符') return value def validate_pwd(self, value): print(value) return value def validate(self, attrs): print(attrs) return attrs def create(self, validated_data): """ 当执行save方法时,自动调用。instance未传值 :param validated_data: :return: """ print(validated_data) return models.UserInfo.objects.create(**validated_data) def update(self, instance, validated_data): """ 当执行save方法时,自动调用。instance传值 :param instance: :param validated_data: :return: """ instance.username = validated_data.get('username', instance.username) instance.save() return instance
状态码(status codes)
服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。
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 - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

浙公网安备 33010602011771号