为什么要前后端分离
1.pc, app, pad多端适应
2. SPA开发模式开始流行(单页Web应用)
3.前后端开发职责不清
4.开发效率问题,前后端互相等待
5.前端一直配合后端,能力受限
6. 后台开发语言和模版高度耦合,导致开发语言依赖严重
前后端分离缺点
1.前后端学习门槛增加
2.数据依赖导致文档重要性增加
3.前端工作量加大
4.SEO的难度加大
5.后端开发模式迁移增加成本
Restful API
restful api是目前前后端分离的最佳实践
1.轻量,直接通过http,不需要额外的协议,post/get/put/delete操作
2.面向资源,一目了然,具有自解释性
3.数据描述简单,一般通过json或者xml做数据通信
理解RESTful架构:http://www.ruanyifeng.com/blog/2011/09/restful.html
RESTful实践:http://www.ruanyifeng.com/blog/2014/05/restful_api.html
1.APIView
使用Serializer方式
from rest_framework import serializers
from .models import Goods
class GoodsSerializer(serializers.Serializer):
name = serializers.CharField(required=True, max_length=100)
click_num = serializers.IntegerField(default=0)
goods_front_image = serializers.ImageField()
add_time = serializers.DateTimeField()
def create(self, validated_data):
return Goods.objects.create(**validated_data)
使用ModelSerializer
from rest_framework import serializers
from .models import Goods, GoodsCategory
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = GoodsCategory
fields = ('name',)
class GoodsSerializer(serializers.ModelSerializer):
category = CategorySerializer()
class Meta:
model = Goods
fields = ('name', 'category', 'click_num', 'goods_front_image', 'add_time')
API View
from rest_framework.views import APIView, status
from rest_framework.response import Response
from .serializer import GoodsSerializer
from .models import Goods
class GoodsListView(APIView):
"""
Goods Api
"""
def get(self, request, format=None):
goods = Goods.objects.all()[:10]
goods_serialier = GoodsSerializer(goods, many=True)
return Response(goods_serialier.data)
# 处理post上来的数据
def post(self, request, format=None):
serializer = GoodsSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
2.GenericView
from rest_framework import mixins
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from .serializer import GoodsSerializer
from .models import Goods
class GoodsPagination(PageNumberPagination):
page_size = 10
page_query_param = 'p'
page_size_query_param = 'page_size'
max_page_size = 100
class GoodsListView(mixins.ListModelMixin, generics.GenericAPIView):
"""
Goods Api
"""
queryset = Goods.objects.all()
serializer_class = GoodsSerializer
pagination_class = GoodsPagination
def get(self,request, *awgs, **kwargs):
return self.list(request, *awgs, **kwargs)
在generic中
ListAPIView 继承了mixins.ListModelMixin, GenericAPIView, 定义了get方法
CreateAPIView 继承了mixins.CreateModelMixin, GenericAPIView, 定义了post方法
所以可以有
class GoodsListView(generics.ListAPIView):
"""
Goods Api
"""
queryset = Goods.objects.all()
serializer_class = GoodsSerializer
pagination_class = GoodsPagination
3.Viewsets and router
使用ModelViewSet
from rest_framework import viewsets
from rest_framework.pagination import PageNumberPagination
from .serializer import GoodsSerializer
from .models import Goods
class GoodsPagination(PageNumberPagination):
page_size = 10
page_query_param = 'p'
page_size_query_param = 'page_size'
max_page_size = 100
class GoodsListViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides
`list`, `create`, `retrieve`,
`update` and `destroy`
actions.
"""
queryset = Goods.objects.all()
serializer_class = GoodsSerializer
pagination_class = GoodsPagination
使用router
在urls.py上加
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'goods', GoodsListViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
]
各个View的继承关系
由上往下继承
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass
class ViewSetMixin(object):
class GenericAPIView(views.APIView):
"""
Base class for all other generic views.
"""
class APIView(View):
# The following policies may be set at either globally, or per-view.
最底层继承Django的View
Comments