Django REST framework 是一個強大且靈活的工具包,用以構建Web APIs。 html
- 在線可視的API,對於贏得你的開發者們十分有用
- 驗證策略涵蓋了OAuth1a和OAuth2
- 同時支持ORM和非ORM數據源的序列化
- 能夠配置各個環節,若無需更多強大的特性,使用通常基於類(function-based)的視圖(views)便可
- 大量的文檔,強力的社區支持
- 大公司如同Mozilla和Eventbrite,也是忠實的使用者python
REST framework 有如下的要求:django
下面是可選的包:json
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
,
}
|
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
|
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()),
]
|
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__'
|
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()
|
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包下面的類會幫咱們處理數據,咱們調用對應的方法而且將其返回值返回便可,api
可是須要注意的是,若是使用此方法,urls.py的url對應的id要命名爲pk,以下:restful
1
2
|
url(r
'^publishes/$'
, views.PublishView.as_view()),
url(r
'^publishes/(?P<pk>\d+)/$'
, views.PublishDetailView.as_view()),
|
可是,即便咱們用了這種封裝,不少代碼仍是有重複的,全部,rest_framework又給咱們作了一層封裝markdown
只須要改變一下XXXView類的繼承類app
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表分紅兩個視圖,那,有沒有一種方法能將他們合併在一塊兒呢?ide
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
BookViewSet(viewsets.ModelViewSet):
queryset
=
models.Book.objects.
all
()
serializer_class
=
serializer.BookSerializers
|
INSTALLED_APPS = [ .... 'rest_framework', ]
from django.db import models class Book(models.Model): title=models.CharField(max_length=32) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish",on_delete=models.CASCADE) authors=models.ManyToManyField("Author") def __str__(self): return self.title class Publish(models.Model): name=models.CharField(max_length=32) email=models.EmailField() def __str__(self): return self.name class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() def __str__(self): return self.name
########### urls.py ############## from django.contrib import admin from django.urls import path,re_path,include urlpatterns = [ re_path("testrestfulframework/",include("testrestfulframework.urls")), ] ########### testrestfulframework/urls.py ############## from django.contrib import admin from django.urls import path,re_path,include from testrestfulframework import views urlpatterns = [ re_path(r'^books/$', views.BookViewSet.as_view(),name="book_list"), re_path(r'^books/(?P<pk>\d+)$', views.BookDetailViewSet.as_view(),name="book_detail"), re_path(r'^publishers/$', views.PublishViewSet.as_view(),name="publish_list"), re_path(r'^publishers/(?P<pk>\d+)$', views.PublishDetailViewSet.as_view(),name="publish_detail"), re_path(r'^authors/$', views.AuthorViewSet.as_view(), name="authorlist"), re_path(r'^authors/(?P<pk>\d+)$', views.AuthorDetailViewSet.as_view(), name="author_detail"), # re_path(r'^books/$', views.BookViewSet.as_view(**{"get":"list","post":"create"}),name="book_list"), # re_path(r'^books/(?P<pk>\d+)$', views.BookViewSet.as_view(**{'get': 'retrieve','put': 'update','patch': 'partial_update','delete': 'destroy'}),name="book_detail"), ]
from rest_framework.views import APIView from rest_framework.response import Response from django.shortcuts import HttpResponse from rest_framework import mixins from .models import * from rest_framework import generics from rest_framework import serializers class BookSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # depth=1 class BookViewSet(APIView): def get(self,request,*args,**kwargs): book_list=Book.objects.all() bs=BookSerializers(book_list,many=True,context={"request":request}) return Response(bs.data) def post(self, request, *args, **kwargs): bs = BookSerializers(data=request.data, many=False,context={"request":request}) if bs.is_valid(): # print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) class BookDetailViewSet(APIView): def get(self,request,*args,**kwargs): book_obj=Book.objects.filter(pk=kwargs["pk"]).first() bs=BookSerializers(book_obj,context={"request":request}) return Response(bs.data) def put(self,request,*args,**kwargs): book_obj=Book.objects.filter(pk=kwargs["pk"]).first() bs=BookSerializers(book_obj,data=request.data,context={"request":request}) if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) def patch(self,request,*args,**kwargs): book_obj=Book.objects.filter(pk=kwargs["pk"]).first() bs=BookSerializers(book_obj,data=request.data,context={"request":request},partial="partial") if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) def delete(self,request,*args,**kwargs): # 這裏是本身寫的,沒找到網上相關 book_obj=Book.objects.filter(pk=kwargs["pk"]).first() if book_obj: book_obj.delete() return Response("delete done") else: return Response("no such data")
from .models import * from rest_framework import mixins from rest_framework import generics from rest_framework import serializers class BookSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # depth=1 class BookViewSet(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 BookDetailViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializers 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) def patch(self,request,*args,**kwargs): return self.partial_update(request,*args,**kwargs)
from .models import * from rest_framework import generics from rest_framework import serializers class BookSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # depth=1 class BookViewSet(generics.ListCreateAPIView): queryset = Book.objects.all() serializer_class = BookSerializers class BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView): queryset = Book.objects.all() serializer_class = BookSerializers
以上均試驗成功。
from rest_framework.views import APIView from rest_framework.response import Response from .models import * from django.shortcuts import HttpResponse from rest_framework import serializers class BookSerializers(serializers.Serializer): title=serializers.CharField(max_length=32) price=serializers.IntegerField() pub_date=serializers.DateField() publish=serializers.CharField(source="publish.name") #authors=serializers.CharField(source="authors.all") authors=serializers.SerializerMethodField() def get_authors(self,obj): temp=[] for author in obj.authors.all(): # temp.append(author.name) # temp.append((author.name,author.age,author.id)) temp.append({"id":author.id,"name":author.name,"age":author.age}) return temp class BookViewSet(APIView): def get(self,request,*args,**kwargs): book_list=Book.objects.all() # 序列化方式1: # from django.forms.models import model_to_dict # data=[] # for obj in book_list: # data.append(model_to_dict(obj)) # print(data) # return HttpResponse(data) # 序列化方式2: # from django.core import serializers as dcs # 跟from rest_framework import serializers名字衝突了 # data=dcs.serialize("json",book_list) # return HttpResponse(data) # 序列化方式3: bs=BookSerializers(book_list,many=True) return Response(bs.data) views.py
from rest_framework.views import APIView from rest_framework.response import Response from .models import * from django.shortcuts import HttpResponse from rest_framework import serializers class BookSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # depth = 1 class BookViewSet(APIView): def get(self,request,*args,**kwargs): book_list=Book.objects.all() # 序列化方式1: # from django.forms.models import model_to_dict # data=[] # for obj in book_list: # data.append(model_to_dict(obj)) # print(data) # return HttpResponse(data) # 序列化方式2: # from django.core import serializers as dcs # 跟from rest_framework import serializers名字衝突了 # data=dcs.serialize("json",book_list) # return HttpResponse(data) # 序列化方式3: bs=BookSerializers(book_list,many=True) return Response(bs.data) def post(self, request, *args, **kwargs): bs = BookSerializers(data=request.data, many=False) if bs.is_valid(): # print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors)
from rest_framework.views import APIView from rest_framework.response import Response from .models import * from django.shortcuts import HttpResponse from rest_framework import serializers class BookSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # exclude = ['authors',] # depth=1 # def create(self, validated_data): # authors = validated_data.pop('authors') # print(authors) # obj = Book.objects.create(**validated_data) # obj.authors.add(*authors) # return obj class BookViewSet(APIView): def get(self,request,*args,**kwargs): book_list=Book.objects.all() # 序列化方式1: # from django.forms.models import model_to_dict # data=[] # for obj in book_list: # data.append(model_to_dict(obj)) # print(data) # return HttpResponse(data) # 序列化方式2: # from django.core import serializers as dcs # 跟from rest_framework import serializers名字衝突了 # data=dcs.serialize("json",book_list) # return HttpResponse(data) # 序列化方式3: bs=BookSerializers(book_list,many=True) return Response(bs.data) def post(self, request, *args, **kwargs): bs = BookSerializers(data=request.data, many=False) if bs.is_valid(): # print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) class BookDetailViewSet(APIView): def get(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj) return Response(bs.data) def put(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj,data=request.data) if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors)
from rest_framework.views import APIView from rest_framework.response import Response from .models import * from django.shortcuts import HttpResponse from rest_framework import serializers class BookSerializers(serializers.ModelSerializer): publish = serializers.HyperlinkedIdentityField( view_name='publish_detail', lookup_field="publish_id", lookup_url_kwarg="pk") class Meta: model = Book fields = "__all__" # depth=1 class PublshSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" # depth = 1 class AuthorSerializers(serializers.ModelSerializer): class Meta: model = Author fields = "__all__" # depth = 1 class BookViewSet(APIView): def get(self,request,*args,**kwargs): book_list=Book.objects.all() # 序列化方式1: # from django.forms.models import model_to_dict # data=[] # for obj in book_list: # data.append(model_to_dict(obj)) # print(data) # return HttpResponse(data) # 序列化方式2: # from django.core import serializers as dcs # 跟from rest_framework import serializers名字衝突了 # data=dcs.serialize("json",book_list) # return HttpResponse(data) # 序列化方式3: # bs=BookSerializers(book_list,many=True) bs=BookSerializers(book_list,many=True,context={"request":request}) return Response(bs.data) def post(self, request, *args, **kwargs): # bs = BookSerializers(data=request.data, many=False) bs = BookSerializers(data=request.data, many=False,context={"request":request}) if bs.is_valid(): # print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) class BookDetailViewSet(APIView): def get(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() # bs=BookSerializers(book_obj) bs=BookSerializers(book_obj,context={"request":request}) return Response(bs.data) def put(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() # bs=BookSerializers(book_obj,data=request.data) bs=BookSerializers(book_obj,data=request.data,context={"request":request}) if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) class PublishViewSet(APIView): def get(self,request,*args,**kwargs): publish_list=Publish.objects.all() bs=PublshSerializers(publish_list,many=True,context={'request': request}) return Response(bs.data) def post(self,request,*args,**kwargs): bs=PublshSerializers(data=request.data,many=False,context={'request': request}) if bs.is_valid(): # print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) class PublishDetailViewSet(APIView): def get(self,request,pk): publish_obj=Publish.objects.filter(pk=pk).first() bs=PublshSerializers(publish_obj,context={'request': request}) return Response(bs.data) def put(self,request,pk): publish_obj=Publish.objects.filter(pk=pk).first() bs=PublshSerializers(publish_obj,data=request.data,context={'request': request}) if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) class AuthorViewSet(APIView): def get(self,request,*args,**kwargs): author_list=Author.objects.all() bs=AuthorSerializers(author_list,many=True,context={'request': request}) return Response(bs.data) def post(self,request,*args,**kwargs): bs=AuthorSerializers(data=request.data,many=False,context={'request': request}) if bs.is_valid(): # print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) class AuthorDetailViewSet(APIView): def get(self,request,pk): Author_obj=Author.objects.filter(pk=pk).first() bs=AuthorSerializers(Author_obj,context={'request': request}) return Response(bs.data) def put(self,request,pk): Author_obj=Author.objects.filter(pk=pk).first() bs=AuthorSerializers(Author_obj,data=request.data,context={'request': request}) if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors)
暫時未找到多對多的超連接
from rest_framework.views import APIView from rest_framework.response import Response from .models import * from django.shortcuts import HttpResponse from rest_framework import serializers from rest_framework import mixins from rest_framework import generics class BookSerializers(serializers.ModelSerializer): publish = serializers.HyperlinkedIdentityField( view_name='publish_detail', lookup_field="publish_id", lookup_url_kwarg="pk") class Meta: model = Book fields = "__all__" # depth=1 class PublshSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" # depth = 1 class AuthorSerializers(serializers.ModelSerializer): class Meta: model = Author fields = "__all__" # depth = 1 class BookViewSet(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 BookDetailViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializers 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)
from rest_framework.views import APIView from rest_framework.response import Response from .models import * from django.shortcuts import HttpResponse from rest_framework import serializers class BookSerializers(serializers.ModelSerializer): publish = serializers.HyperlinkedIdentityField( view_name='publish_detail', lookup_field="publish_id", lookup_url_kwarg="pk") class Meta: model = Book fields = "__all__" # depth=1 class PublshSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" # depth = 1 class AuthorSerializers(serializers.ModelSerializer): class Meta: model = Author fields = "__all__" # depth = 1 from rest_framework import mixins from rest_framework import generics class BookViewSet(generics.ListCreateAPIView): queryset = Book.objects.all() serializer_class = BookSerializers class BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView): queryset = Book.objects.all() serializer_class = BookSerializers class PublishViewSet(generics.ListCreateAPIView): queryset = Publish.objects.all() serializer_class = PublshSerializers class PublishDetailViewSet(generics.RetrieveUpdateDestroyAPIView): queryset = Publish.objects.all() serializer_class = PublshSerializers class AuthorViewSet(generics.ListCreateAPIView): queryset = Author.objects.all() serializer_class = AuthorSerializers class AuthorDetailViewSet(generics.RetrieveUpdateDestroyAPIView): queryset = Author.objects.all() serializer_class = AuthorSerializers
測試經過,與上相似,略,
from .models import * from rest_framework import serializers class BookSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # depth=1 from rest_framework import viewsets class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializers
from django.urls import path,re_path,include from testrestfulframework import views urlpatterns = [ re_path(r'^books/$', views.BookViewSet.as_view({"get":"list","post":"create"}),name="book_list"), re_path(r'^books/(?P<pk>\d+)$', views.BookViewSet.as_view({ 'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy' }),name="book_detail"), # re_path(r'^books/$', views.BookViewSet.as_view(),name="book_list"), # re_path(r'^books/(?P<pk>\d+)$', views.BookDetailViewSet.as_view(),name="book_detail"), ]