您好,登录后才能下订单哦!
目录
django rest framework. 1
serializers.Serializer. 1
serializers.ModelSerializer:... 3
api FBV:... 4
rest_framework.request.Request和rest_framework.response.Response:... 5
rest_framework.decorators.api_view和rest_framework.views.APIView:... 5
api CBV,rest_framework.views.APIView:... 6
api CBV,使用rest_framework.mixins:... 7
api CBV,使用generics.ListCreateAPIView和generics.RetrieveUpdateDestroyAPIView:... 8
分页:... 9
认证:... 9
授权:... 10
是django用来restful api的框架,风格完全和django一样,使用起来像是django本身提供的;
https://www.django-rest-framework.org/
(webproject) C:\webproject\mysite>pip install djangorestframework
INSTALLED_APPS = [
'rest_framework',
rest_framework.serializers.Serializer和django.forms.Form:
功能一样,都是将用户提交的数据转为py数据结构,可用此来完成校验;
Form用在post提交中的form表单;
Serializer用在用户提交的json;
from rest_framework import serializers
from .models import Author
class AuthorSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
first_name = serializers.CharField(max_length=100)
last_name = serializers.CharField(required=False, allow_blank=True, max_length=100)
email = serializers.EmailField(required=False, allow_blank=True, max_length=100)
def create(self, validated_data):
return Author.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.first_name = validated_data.get('first_name', instance.first_name)
instance.last_name = validated_data.get('last_name', instance.last_name)
instance.email = validated_data.get('email', instance.email)
instance.save()
return instance
底层实现:
>>> from books.serializer import AuthorSerializer
>>> from rest_framework.renderers import JSONRenderer #py结构-->json
>>> from rest_framework.parsers import JSONParser #json-->py结构
>>> from books.models import Author
>>> Author.objects.all()
<QuerySet [<Author: chai jowin>, <Author: dsfdfd sfdsfdsf>]>
>>> a = Author.objects.get(id=1)
>>> s = AuthorSerializer(a)
>>> s.data #dict
{'last_name': 'jowin', 'email': 'jowin@chai.com', 'id': 1, 'first_name': 'chai'}
>>> content = JSONRenderer().render(s.data)
>>> content
b'{"id":1,"first_name":"chai","last_name":"jowin","email":"jowin@chai.com"}'
>>> from django.utils.six import BytesIO
>>> stream = BytesIO(content)
>>> stream
<_io.BytesIO object at 0x00000000046389E8>
>>> data = JSONParser().parse(stream)
>>> data
{'last_name': 'jowin', 'email': 'jowin@chai.com', 'id': 1, 'first_name': 'chai'}
>>> s = AuthorSerializer(data=data)
>>> s
AuthorSerializer(data={'last_name': 'jowin', 'email': 'jowin@chai.com', 'id': 1, 'first_name': 'chai'}):
id = IntegerField(read_only=True)
first_name = CharField(max_length=100)
last_name = CharField(allow_blank=True, max_length=100, required=False)
email = EmailField(allow_blank=True, max_length=100, required=False)
>>> s.is_valid()
True
>>> s.validated_data #返回ordereddict
OrderedDict([('first_name', 'chai'), ('last_name', 'jowin'), ('email', 'jowin@chai.com')])
>>> s.save()
<Author: chai jowin>
>>> Author.objects.all()
<QuerySet [<Author: chai jowin>, <Author: dsfdfd sfdsfdsf>, <Author: chai jowin>]>
>>> s = AuthorSerializer(Author.objects.all(), many=True) #序列化多个对象时要加many=True,调用many_init()
>>> s.data
[OrderedDict([('id', 1), ('first_name', 'chai'), ('last_name', 'jowin'), ('email', 'jowin@chai.com')]), OrderedDict([('id', 2), ('first_name', 'dsfdfd'), ('la
st_name', 'sfdsfdsf'), ('email', 'dsfdsf@dsfdsf.com')]), OrderedDict([('id', 3), ('first_name', 'chai'), ('last_name', 'jowin'), ('email', 'jowin@chai.com')])
]
rest_framework.serializers.ModelSerializer同django.forms.ModelForm;
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ['id', 'first_name', 'last_name', 'email']
from django.http import HttpResponse
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from .serializer import AuthorSerializer
from .models import Author
from django.views.decorators.csrf import csrf_exempt
class JSONResponse(HttpResponse): #可用django.http.JsonResponse
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs) #同super().__init__(content, **kwargs)
@csrf_exempt
def author_list(request):
if request.method == 'GET':
authors = Author.objects.all()
serializer = AuthorSerializer(authors, many=True)
return JsonResponse(serializer.data, safe=False) # 默认safe=True,In order to allow non-dict objects to be serialized set the safe parameter to False.
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = AuthorSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JSONResponse(serializer.data, status=201)
return JSONResponse(serializer.errors, status=400)
@csrf_exempt
def author_detail(request, pk):
try:
author = Author.objects.get(pk=pk)
except Author.DoesNotExist:
return JSONResponse(status=404)
if request.method == 'GET':
serializer = AuthorSerializer(author)
return JSONResponse(serializer.data)
elif request.method == 'PUT':
data = JSONParser().parse(request)
serializer = AuthorSerializer(author, data=data)
if serializer.is_valid():
serializer.save()
return JSONResponse(serializer.data)
return JSONResponse(serializer.errors, status=400)
elif request.method == 'DELETE':
author.delete()
return JSONResponse('', status=204)
url(r'^authors/$', api.author_list, name='author_list'),
url(r'^authors/(?P<pk>[0-9]+)/$', api.author_detail, name='author_detail'),
request.POST # Only handles form data. Only works for 'POST' method.
request.data # Handles arbitrary data. Works for 'POST', 'PUT' and 'PATCH' methods.
return Response(data) # Renders to content type as requested by the client.根据客户端的请求渲染内容类型
The @api_view decorator for working with function based views.
The APIView class for working with class-based views. #同django.views.View
例,@api_view:
@api_view(['GET', 'POST']) #只作为接口使用,用browser访问报WrappedAttributeError,'CSRFCheck' object has no attribute 'process_request'
@csrf_exempt
def author_list(request):
if request.method == 'GET':
authors = Author.objects.all()
serializer = AuthorSerializer(authors, many=True)
# return JSONResponse(serializer.data)
# return JsonResponse(serializer.data, safe=False)
return Response(serializer.data)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = AuthorSerializer(data=data)
if serializer.is_valid():
serializer.save()
# return JsonResponse(serializer.data, status=201)
return Response(serializer.data, status=201)
# return JsonResponse(serializer.errors, status=400)
return Response(serializer.errors, status=400)
用postman测GET和POST;
from rest_framework.views import APIView
from rest_framework import status
from django.http import Http404
class AuthorList(APIView):
def get(self, request, format=None):
authors = Author.objects.all()
serializer = AuthorSerializer(authors, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = AuthorSerializer(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)
class AuthorDetail(APIView):
def get_object(self, pk):
try:
return Author.objects.get(pk=pk)
except Author.DoesNotExist:
return Http404
def get(self, request, pk, format=None):
author = self.get_object(pk)
serializer = AuthorSerializer(author)
return Response(serializer.data)
def put(self, request, pk, format=None):
author = self.get_object(pk)
serializer = AuthorSerializer(author, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
author = self.get_object(pk)
author.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
# url(r'^authors/$', api.author_list, name='author_list'),
url(r'^authors/$', AuthorList.as_view()),
# url(r'^authors/(?P<pk>[0-9]+)/$', api.author_detail, name='author_detail'),
url(r'^authors/(?P<pk>[0-9]+)/$', AuthorDetail.as_view()),
from rest_framework import mixins
from rest_framework import generics
class AuthorList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
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 AuthorDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
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 import generics
class AuthorList(generics.ListCreateAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
class AuthorDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
postman测试时,PUT方法注意要用JSON;
REST_FRAMEWORK = {
# 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
"PAGE_SIZE": 2,
django支持认证方式:
Basic,默认;
Session;
Token;
自定义认证;
默认用Basic认证,输入Username和Password,会自动生成到Headers中,用base64加密;
例,使用token认证:
INSTALLED_APPS = [
'rest_framework.authtoken',
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
# 'rest_framework.authentication.BasicAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
)
}
(webproject) C:\webproject\mysite>python manage.py makemigrations
(webproject) C:\webproject\mysite>python manage.py migrate
>>> from django.contrib.auth.models import User
>>> from rest_framework.authtoken.models import Token
>>> t = Token.objects.create(user=User.objects.get(id=1))
>>> t.key
'219c0ec96617256b93b36d0ab95b70e7c893ac1b'
例,用session认证:
KEY中Cookie,VALUE中粘贴网页中Network中csrftoken;
https://www.django-rest-framework.org/api-guide/permissions/#api-reference
rest_framework内置权限:
AllowAny
IsAuthenticated
IsAdminUser
IsAuthenticatedOrReadOnly
DjangoModelPermissions
DjangoModelPermissionsOrAnonReadOnly
DjangoObjectPermissions
REST_FRAMEWORK = {
"PAGE_SIZE": 1,
"DEFAULT_AUTHENTICATION_CLASSES": (
# 'rest_framework.authentication.BasicAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
'rest_framework.permissions.IsAuthenticated', #全局配置默认权限
)
}
例,view中使用权限控制:
from rest_framework import generics
from rest_framework import permissions
class AuthorList(generics.ListCreateAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
permission_classes = (permissions.IsAuthenticated,) #多个是and的关系
例,自定义权限:
from rest_framework import generics
from rest_framework import permissions
class IsSuperUser(permissions.BasePermission): #继承permissions.BasePermission,重写has_permission()
def has_permission(self, request, view):
return request.user.is_superuser()
class AuthorList(generics.ListCreateAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
# permission_classes = (permissions.IsAuthenticated,)
permission_classes = (IsSuperUser,)
ViewSet与View,不同之处在于ViewSet提供read或update之类的操作,而不是get或put等方法处理程序;当它被实例化成一组视图的时候,通过使用Router类来处理自己定义的url;
例:
from rest_framework import viewsets
class AuthorViewSet(viewsets.ReadOnlyModelViewSet): #仅提供list和detail操作
queryset = Author.objects.all()
serializer_class = AuthorSerializer
# permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
例:
from rest_framework import viewsets
class AuthorViewSet(viewsets.ModelViewSet): #提供list|create|retrieve|update|destroy
queryset = Author.objects.all()
serializer_class = AuthorSerializer
# permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
author_list = AuthorViewSet.as_view({
'get': 'list',
'post': 'create'
})
author_detail = AuthorViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'pathch': 'partial_update',
'delete': 'destroy',
})
# url(r'^authors/$', api.author_list, name='author_list'),
# url(r'^authors/$', AuthorList.as_view()),
url(r'^authors/$', author_list, name='author-list'),
# url(r'^authors/(?P<pk>[0-9]+)/$', api.author_detail, name='author_detail'),
# url(r'^authors/(?P<pk>[0-9]+)/$', AuthorDetail.as_view()),
url(r'^authors/(?P<pk>[0-9]+)/$', author_detail, name='author-detail'),
例,使用routers:
from rest_framework import viewsets
class AuthorViewSet(viewsets.ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
# permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
router = DefaultRouter()
router.register(r'authors', AuthorViewSet)
urlpatterns = [
……
]
urlpatterns += router.urls #方式1
# urlpatterns += [ #方式2
# url(r'^', include(router.urls)),
# ]
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。