成都网站建设设计

将想法与焦点和您一起共享

103django_rest-framework

 

创新互联是一家集网站建设,房县企业网站建设,房县品牌网站建设,网站定制,房县网站建设报价,网络营销,网络优化,房县网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

目录

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 rest framework

 

是django用来restful api的框架,风格完全和django一样,使用起来像是django本身提供的;

 

https://www.django-rest-framework.org/

 

(webproject) C:\webproject\mysite>pip install djangorestframework

 

INSTALLED_APPS = [

    'rest_framework',

 

 

serializers.Serializer

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()

, ]>

>>> 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.objects.all()

, , ]>

>>> 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')])

]

 

 

serializers.ModelSerializer:

 

rest_framework.serializers.ModelSerializer同django.forms.ModelForm;

 

 

class AuthorSerializer(serializers.ModelSerializer):

    class Meta:

        model = Author

        fields = ['id', 'first_name', 'last_name', 'email']

 

 

api FBV:

 

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[0-9]+)/$', api.author_detail, name='author_detail'),

 

 

rest_framework.request.Request和rest_framework.response.Response:

 

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.根据客户端的请求渲染内容类型

 

 

rest_framework.decorators.api_view和rest_framework.views.APIView:

 

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;

 

 

api CBV,rest_framework.views.APIView:

 

 

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[0-9]+)/$', api.author_detail, name='author_detail'),

    url(r'^authors/(?P[0-9]+)/$', AuthorDetail.as_view()),

 

 

api CBV,使用rest_framework.mixins:

 

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)

 

 

api CBV,使用generics.ListCreateAPIView和generics.RetrieveUpdateDestroyAPIView:

 

 

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

 

103django_rest-framework

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;

自定义认证;

 

103django_rest-framework

默认用Basic认证,输入Username和Password,会自动生成到Headers中,用base64加密;

103django_rest-framework

 

 

例,使用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'

 

103django_rest-framework

 

 

例,用session认证:

103django_rest-framework

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,)

 

 

rest_framework.viewsets和rest_framework.routers.DefaultRouter:

 

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[0-9]+)/$', api.author_detail, name='author_detail'),

    # url(r'^authors/(?P[0-9]+)/$', AuthorDetail.as_view()),

    url(r'^authors/(?P[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)),

# ]

 


网站名称:103django_rest-framework
文章链接:http://chengdu.cdxwcx.cn/article/jojpjg.html