初步使用 apiview源码

rest-framework是基于django中的CBV开发(依赖django)

为什么有restful,因为按照我们原来的开发,一张表要对应增删改查4条路由,而rest-framework是面向资源开发一张表只对应一条url(ROA) 针对不同的请求类型来返回相应结果。

GET books/			 :获取多个数据
GET books/2 		 	 :获取某一本数据
POST books			:添加一本数据,来自请求体
PUT /books/1			:对1 这本书籍进行编辑
PATCH /books/1		:对1 这本书籍进行编辑
DELETE /books/1 		:对1 进行删除操作

如何使用rest-framework

1. 下载组件

`pip install djangorestframework`

 

2. 创建一个django项目然后在settings文件的 INSTALLED_APPS 中添加 rest_framework

3. 创建一个router.py在文件中引入

from app01.models import * # 引入所要操作的表
from rest_framework import serializers # 继承的序列化表

class BookSeriaizer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Book
        field = '__all__'
        
# 用法和modelform一毛一样

  

4.在view中配置

from app01 import router
from rest_framework import viewsets

class BookViewSet(views.ModelViewSet):
    queryset = Book.objects.all() # 对应的所有数据
    serializer_class = BookSerializer

  

5. 配置相应的路由

实例化一个routers.DefaultRouter()对象,然后在这个对象中注册相应的视图

from django.conf.urls import url, include
from rest_framework import routers
from app01 import views

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
router.register(r'books', views.BookViewSet)

urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

  


 

怎么实现和rest-framework相同的功能呢,创建序列化组件

  我们可以观察到rest-framework返回的数据是json的字符串我们有很多种方法可以返回json的字符串

class BookView(APIView):

    def get(self, request, *args, **keargs):
        # 方法一
        # book_list = list(Book.objects.all().values('title', 'price'))
        # return HttpResponse(json.dumps(book_list))

        # 方法二
        # book_list = Book.objects.all()
        # temp = []
        # for book in book_list:
        #     temp.append({
        #         'title': book.title,
        #         'price': book.price,
        #         'pub_date': book.pub_date.strftime('%Y-%m')
        #     })
        # return HttpResponse(json.dumps(temp))

        # 方法三
        # book_list = Book.objects.all()
        # from django.core import serializers
        # temp = serializers.serialize('json', book_list)
        # return HttpResponse(temp)

        # 方法四
        book_list = Book.objects.all()
        bs = BookSerializer(book_list, many=True)
        return Response(bs.data)

  实际第三种方法已经很简单了,但是我们选择第四种方法,因为我们不仅要把数据变成json字符串返回给前端还要把,前端返回给我们的json字符串变为queryset对象。

# class BookSerializer(serializers.Serializer):
#     title = serializers.CharField(max_length=32)
#     price = serializers.IntegerField()
#     pub_date = serializers.DateField()
#     publish = serializers.CharField(source='publish.name')
#     authors = serializers.SerializerMethodField()
#
#     def get_authors(self,obj):
#         temp = []
#         for author in obj.authors.all():
#             temp.append({'pk': author.pk, 'name': author.name})
#         return temp

类似于modelform的方法 class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__'
# 单独定义authors方法:多对多字段 authors = serializers.SerializerMethodField() def get_authors(self, obj): temp = [] for author in obj.authors.all(): temp.append({'pk': author.pk, 'name': author.name}) return temp

 

创建相对应的视图函数

class BookView(APIView):
  def get(self, request, *args, **kwargs)   book_list = Book.objects.all()   bs = BookSerializers(book_list, many=True)   return Response(bs.data)

 每创建一个对应的视图函数都是要重复代码。

优化:

优化方案一:

  

from rest_framework import mixins
from rest_framework import generics
class BookView(mixins.ListModelMixin,
               mixins.CreateModelMixin,
               generics.GenericAPIView):

    queryset = Book.objects.all()
    serializer_class = BookSerializers

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):   
        return self.create(request, *args, **kwargs)

class BookDetailView(
			mixins.RetrieveModelMixin,
			mixins.DestroyModelMixin,
			mixins.UpdateModelMixin,
			generics.GenericAPIView ):
			
    queryset = Book.objects.all()
    serializer_class = BookSerializers

    def get(self,request, *args, **kwargs):    
        return self.retrieve(request, *args, **kwargs)

    def delete(self,request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

    def put(self,request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

  

优化方案二:

from rest_framework import generics
   
class BookView(generics.ListCreateAPIView):
		queryset = Book.objects.all()
		serializer_class = BookSerializers

	
class BookDetailView(generics.RetrieveUpdateDestroyAPIView):
		queryset = Book.objects.all()
		serializer_class = BookSerializers
					

  

优化方案三:

通过在as_view中定义的字典发射去找相对应的方法。

urls.py:
    url(r"books/$",views.BookView.as_view({'get':'list', 'post':'create'}),name="book_list"),
	url(r"books/(?P<pk>\d+)/$",views.BookView.as_view({'get':'retrieve','put': 'update','delete': 'destroy'}),name="book_detail"),

    
  views.py:
  
      class BookViewSet(ModelViewSet):
		queryset = Book.objects.all()
		serializer_class = BookSerializers

  

 

posted @ 2018-04-11 15:02  沈俊杰  阅读(92)  评论(0)    收藏  举报