初步使用 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

浙公网安备 33010602011771号