为什么要前后端分离

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