rest_framework基础
简介
为什么要使用REST framework?
Django REST framework 是一个强大且灵活的工具包,用以构建Web APIs。
- 在线可视的API,对于赢得你的开发者们十分有用
- 验证策略涵盖了OAuth1a和OAuth2
- 同时支持ORM和非ORM数据源的序列化
- 可以配置各个环节,若无需更多强大的特性,使用一般基于类(function-based)的视图(views)即可
- 大量的文档,强力的社区支持
- 大公司如同Mozilla和Eventbrite,也是忠实的使用者
配置要求
REST framework 有以下的要求:
- Python (2.7, 3.2, 3.3, 3.4, 3.5)
- Django (1.7+, 1.8, 1.9)
下面是可选的包:
- Markdown (2.1.0+) - Markdown为可视化 API 提供了支持.
- django-filter (0.9.2+) - 过滤支持.
- django-crispy-forms - 为过滤,提供了改良的HTML呈现.
- django-guardian (1.1.1+) - 对象层面的权限支持.
安装与配置
安装
1
2
3
|
pip install djangorestframework pip install markdown # 可选依赖包 pip install django - filter # 可选依赖包 |
配置
1
2
3
4
5
6
7
8
9
10
|
INSTALLED_APPS = ( ... 'rest_framework' , ) REST_FRAMEWORK = { # 编码格式 'UNICODE_JSON' : False , } |
基本使用方法
models.py
1
2
3
4
5
6
7
|
from django.db import models class Author(models.Model): name = models.CharField(max_length = 32 ) age = models.IntegerField() def __str__( self ): return self .name |
urls.py
1
2
3
4
5
6
7
8
|
from django.conf.urls import url from django.contrib import admin from rest_demoimport views urlpatterns = [ url(r '^admin/' , admin.site.urls), url(r '^authors/$' , views.AuthorsView.as_view()), url(r '^authors/(d+)/$' , views.AuthorsDetailView.as_view()), ] |
serializer.py
1
2
3
4
5
6
7
|
from rest_framework import serializers from rest_demo import models class AuthorModelSerializers(serializers.ModelSerializer): class Meta: model = models.Author fields = '__all__' |
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
from rest_demo import serializer from rest_framework.views import APIView from rest_framework.response import Response from rest_demo import models class AuthorsView(APIView): def get( self ,request): ''' 查询所有作者 :param request: :return: ''' author_list = models.Author.objects. all () auts = serializer.AuthorModelSerializers(author_list,many = True ) return Response(auts.data) def post( self ,request): ''' 添加作者 :param request: :return: ''' auts = serializer.AuthorModelSerializers(data = request.data) if auts.is_valid(): auts.save() return Response(auts.data) return Response(auts.errors) class AuthorsDetailView(APIView): def get( self ,request, id ): ''' 查询单条作者 :param request: :param id: :return: ''' author = models.Author.objects. filter (pk = id ).first() auts = serializer.AuthorModelSerializers(author) return Response(auts.data) def put( self ,request, id ): ''' 修改单条作者 :param request: :param id: :return: ''' author = models.Author.objects. filter (pk = id ).first() auts = serializer.AuthorModelSerializers(instance = author,data = request.data) if auts.is_valid(): auts.save() return Response(auts.data) return Response(auts.errors) def delete( self ,request, id ): ''' 删除单条作者 :param request: :param id: :return: ''' models.Author.objects. filter (pk = id ).delete() return Response() |
封装
继承mixin包下面的类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
from rest_framework import mixins from rest_framework import generics class PublishView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView): queryset = models.Publish.objects. all () serializer_class = serializer.PublishSerializers 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 PublishDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView): queryset = models.Publish.objects. all () serializer_class = serializer.PublishSerializers def get( self ,request, * args, * * kwargs): return self .retrieve(request, * args, * * kwargs) def put( self ,request, * args, * * kwargs): return self .update(request, * args, * * kwargs) def delete( self ,request, * args, * * kwargs): return self .destroy(request, * args, * * kwargs) |
这个时候,我们只需要提供queryset和serializer_class两个参数配置,mixin包下面的类会帮我们处理数据,我们调用对应的方法并且将其返回值返回即可,
但是需要注意的是,如果使用此方法,urls.py的url对应的id要命名为pk,如下:
1
2
|
url(r '^publishes/$' , views.PublishView.as_view()), url(r '^publishes/(?P<pk>d+)/$' , views.PublishDetailView.as_view()), |
但是,即使我们用了这种封装,很多代码还是有重复的,所有,rest_framework又给我们做了一层封装
继承generices包下面的类
只需要改变一下XXXView类的继承类
1
2
3
4
5
6
7
8
9
|
from rest_framework import generics class PublishView(generics.ListCreateAPIView): queryset = models.Publish.objects. all () serializer_class = serializer.PublishSerializers class PublishDetailView(generics.RetrieveUpdateDestroyAPIView): queryset = models.Publish.objects. all () serializer_class = serializer.PublishSerializers |
这样,代码就清晰很多了,但是,这种方法依然是将一个model表分成两个视图,那,有没有一种方法能将他们合并在一起呢?
继承viewsets包下的ModelViewSet
urls.py
1
2
3
4
5
6
7
|
url(r '^books/$' , views.BookViewSet.as_view({ "get" : "list" , "post" : "create" }),name = "book_list" ), url(r '^books/(?P<pk>d+)$' , views.BookViewSet.as_view({ 'get' : 'retrieve' , 'put' : 'update' , 'patch' : 'partial_update' , 'delete' : 'destroy' }),name = "book_detail" ), |
views.py
1
2
3
4
|
from rest_framework import viewsets class BookhViewSet(viewsets.ModelViewSet): queryset = models.Book.objects. all () serializer_class = serializer.PublishSerializers |