关于RESTful的问题,在最近的面试中遇到不少,以前有过必定的了解,但没有系统性的总结分析。因此如今结合Django RESTframework来加深对RESTful的理解,同时梳理这过程的一些知识点。html
这个问题是最容易想到的,首先要分析这个问题,网上的其余文章都会讲到有关REST(Representational State Transfer),中文翻译:”表述性状态传递“,再白话一点就是对资源的表述性状态传递。刚开始,看到这里头都大了,那咱们来看看其中比较关键须要了解到的知识点。前端
这里的资源指的是网络上的每个实体,而每个实体都有着对应的URI(统一资源标识符),若是须要访问这个资源,能够经过访问它的URI便可。python
简单来讲就是资源的表现形式,好比图片、HTML、文本等等。面试
客户端能够经过GET、POST、PUT、DELETE HTTP动词来操做资源。数据库
REST从资源的角度来审视整个网络,将分布再网络中某个结点经过URI进行标识,而客户端和服务端传递的是资源的某种表现层,而且客户端经过HTTP动词,对服务器资源操做,实现”表述性状态转化“。(表述性:客户端请求一个资源,而且经过服务器拿到资源)
知足以上这些约束条件和原则的应用程序或设计就是RESTful。换言之RESTful就是一种架构的规范和约束。django
对API的设计来说,RESTful是现在常见的的设计规范,一般用于Web数据接口的设计。这里讲讲从网上大体总结的几个RESTful API的设计细节。json
客户端使用”动词+宾语"的结构操做服务器资源,动词指的是HTTP动词,宾语指的是资源。HTTP动词对应的服务器资源操做:后端
- GET(SELECT):从服务器取出资源(一项或多项)。
- POST(CREATE):在服务器新建一个资源。
- PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
- PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
- DELETE(DELETE):从服务器删除资源。
因为宾语是API中的URI,是HTTP动词做用的的对象,应该是名词,而不是动词。api
对于URI建议使用复数服务器
客户端的每一次请求,服务器给出回应,而回应包括HTTP状态码和数据两部分。
HTTP状态码的含义:
- 1xx:相关信息
- 2xx:操做成功
- 3xx:重定向
- 4xx:客户端错误
- 5xx:服务器错误
API返回的数据格式,不该该是一个纯文本,应该是一个JSON对象,这样才符合结构化流程。一样服务器回应的HTTP头的Content-Type属性一样要设置为application/json。
在发生错误的时候,不该该返回一个200状态码,而后把错误信息放在数据体里,由于这样会致使须要解析完数据体才能知道操做失败。
Django RestFramework是一个基于Django上构建符合RESTful风格Web api,而且自身还带有测试的页面,方便测试本身的API,因此对于”先后端分离“的开发模式来说十分合适。
先后端分离指的是后端来讲只须要提供数据接口,再也不渲染模板,前端只须要获取数据而且呈现。这样的有许多优势:
- 先后端解耦,接口复用,减小开发量
- 各司其职,先后端同步开发,提高工做效率,定好接口规范
- 更利于调试、测试和运维
Rest Framework基本组件:
- APIView
- 解析器组件:对请求的数据进行解析,根据不一样请求题进行解析
- 序列化组件:相似于Django的Form,能够经过自定义操做得到想要的数据形式
- 视图类(mixin)
- 认证组件
- 权限组件
- 频率组件
- 分页组件
- 响应器组件
- url注册器
关于Django的视图函数,能够基于FBV模式也能够基于CBV模式:
- FBV模式:Django的路由映射表里进行url和视图函数的关联
- CBV模式:而CBV模式则是在views.py中定义视图类,在视图类中视图函数,如(get,post,put,delete)等
Django RESTFramework就是基于CBV模式,当一个http请求到达Django后,首先执行中间件的方法,而后在进行路由匹配。
当路由匹配后,会执行自定义类中的as_view()方法,若是不存在则会调用父类的as_view()方法,最后再调用到dispatch()方法处理不一样request请求,执行不一样的方法。(这段过程当中设计到Django CBV模式的处理流程,以及一些源码知识)
安装Django restframework:
pip install djangorestframework
新建项目,新建应用,修改settings.py
django-admin startproject Crawl cd Crawl python manage.py startapp music
settings.py(将rest_framework新增到INSTALLED_APPS)
(其他的修改数据库配置、修改语言、时区就不一一列出来)
项目文件树:
设计一个有关于存储歌曲的详细信息表(music/models.py):
from django.db import models class Music(models.Model): music_author = models.CharField(max_length=50, verbose_name='歌唱者') music_name = models.CharField(max_length=100, verbose_name='歌曲名') music_album = models.CharField(max_length=100, verbose_name='专辑') music_time = models.CharField(max_length=10, verbose_name='歌曲时间') music_type = models.CharField( max_length=100, null=True, verbose_name='歌曲类型', default=None) music_lyrics = models.CharField( max_length=100, blank=True, verbose_name='做词者') music_arranger = models.CharField( max_length=100, blank=True, verbose_name='做曲者')
同步数据库:
python manage.py makemigrations python manage.py migrate
建立一个序列化Serialier类,提供序列化和反序列化的途径,使之能够转化为如json的表现形式,相似于Django的Form表单的原理。在music目录下,建立serializers.py:
from rest_framework import serializers from music.models import * class MusicSerializer(serializers.ModelSerializer): class Meta: fields = '__all__' model = Music
经过前面提到的CBV模式,设计视图处理函数和路由映射:
Crawl/urls.py
from django.contrib import admin from django.urls import path, include import music urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('music.urls')), ]
music/urls.py
from django.urls import path from music.views import * urlpatterns = [ path('', MusicList.as_view()), path('<int:pk>/', MusicDetail.as_view()), ]
music/views.py
from django.shortcuts import render from rest_framework import generics from rest_framework.views import APIView from rest_framework.response import Response from music.models import * from music.serializers import MusicSerializer # Create your views here. class MusicList(APIView): def get(self, request): queryset = Music.objects.all() ret = MusicSerializer(queryset, many=True) return Response(ret.data) def post(self, request): music = MusicSerializer(data=request.data) if music.is_valid(): music.save() return Response(music.data) else: return Response(music.errors) class MusicDetail(generics.RetrieveAPIView): queryset = Music.objects.all() serializer_class = MusicSerializer
代码详解:
代码比较简单,主要就是继承restframework框架的通用视图函数generics,或者APIView。若是先省事,建议generics,由于提供的通用视图能够容许你快速构建与数据相关的API视图,固然若是以为通用视图不适合本身的API需求,可使用APIView类。
(在这里两种方式都用到了,能够对比他们的区别)
模拟请求API接口(GET、POST请求)
自带的测试页面:
刚开始接触到RESTful方面的知识仍是很是懵的,对网上不少文章感受讲的也不是很全面,因此索性总结一下,而后接触到RESTFramework框架也发现到了不少在Django方面不熟悉的地方,如CBV模式,以及工做的原理,有些都牵扯到框架内的源码,也是从网上一些优秀的文章一点点慢慢了解到,以后对Django RESTframework相关知识也会继续总结学习,下面是我在网上参考的一些文章,有兴趣的能够了解一下。
参考连接:
http://www.javashuo.com/article/p-qqxnnbjs-ct.html
https://www.cnblogs.com/renpingsheng/p/9534984.html#FeedBack
https://www.jianshu.com/p/08a998f74ac7