Django REST framework 를 이용 하여 RESTful API 를 작성 합 니 다.

35095 단어
요즘 Django 를 하고 있어 서 rest 라 고 할 수 밖 에 없어 요.framework 는 정말 큰 신기 입 니 다. 쉽게 심지어 자동화 로 많은 일 을 해결 할 수 있 습 니 다. 예 를 들 어:
RESTful 규범 에 맞 는 API 자동 생 성
OPTION, HEAD, POST, GET, PATCH, PUT, DELETE 지원
근거  Content-Type  데이터 형식 을 동적 으로 되 돌려 줍 니 다 (예 를 들 어 text, json)
브 라 우 저 블 의 대화 형 페이지 생 성 (API 에 매우 우호 적 인 브 라 우 저 페이지 자동 생 성) 매우 세분 화 된 권한 관리 (field 급 까지 세분 화 가능) 설명도
설치 하 다.
$ pip install djangorestframework
$ pip install markdown 

개술
Django Rest framework 의 프로 세 스 는 대략 이 렇 습 니 다.
모델 구축 Serialiers 에 의 해 데이터 베 이 스 를 추출 한 데이터 Parse 를 API 로 하 는 데이터 (클 라 이언 트 에 게 되 돌아 갈 수도 있 고 브 라 우 저 에 표시 할 수도 있 습 니 다) ViewSet 은 views 의 집합 으로 클 라 이언 트 의 요청 (GET, POST 등) 에 따라 Serialiers 가 처리 한 데 이 터 를 되 돌려 줍 니 다.
권한 Premissions 도 이 단계 에서 처리 합 니 다
ViewSet 은 Routers 에 등록 할 수 있 으 며, 등록 하면 Api Root 페이지 에 표 시 됩 니 다 url 에 ViewSet 생 성 view 를 등록 하고 감청 url 을 지정 합 니 다.
전면적 이 고 세밀 하 게 이해 하 기 를 바 라 는 사람 은 공식 문 서 를 보 러 가 십시오. 저 는 한 걸음 한 걸음 자세히 말 하지 않 고 블록 으로 나 누 어 소개 하 겠 습 니 다.
준비 작업 & 모델
작은 종목 을 써 서 연습 하 자.
먼저 쓰다  manage.py startproject rest  하나의 항목 생 성 더욱 사용한다  manage.py createsuperuser  사용자 만 들 기 (뒤쪽 권한 관리 에 사용) 데이터베이스 초기 화  manage.py migrate
그리고 당연히 models 를 작성 하여 rest 를 보 여주 기 위해 서 입 니 다.framework 의 강력 한 점, 나 는 models 에 사용자 정의 field 를 정의 했다.
# myproject/myapp/models.py


#! /usr/bin/env python
# -*- coding: utf-8
from __future__ import unicode_literals, absolute_import import cPickle as pickle from django.db import models from django.contrib.auth.models import User class SerializedField(models.TextField): """        pickle       Python     """ __metaclass__ = models.SubfieldBase #       metaclass      to_python def validate(self, val): raise isinstance(val, basestring) def to_python(self, val): """          ,    python   """ if val and isinstance(val, unicode): return pickle.loads(val.encode('utf-8')) return val def get_prep_value(self, val): """  python object      """ return pickle.dumps(val) class MyModel(models.Model): created_at = models.DateTimeField(auto_now_add=True) #             owner = models.ForeignKey(User, related_name='mymodels') field = models.CharField(max_length=100) options = SerializedField(max_length=1000, default={}) 

Serializers
Models 를 정의 하면 Serializers 를 시작 할 수 있 습 니 다. 이것 은 Django 에 해당 하 는 Form 입 니 다.
# myproject/myapp/serializers.py

#! /usr/bin/env python
# -*- coding: utf-8
from __future__ import unicode_literals, absolute_import import json from django.contrib.auth.models import User from rest_framework import serializers from ..models import MyModel from .fields import MyCustField class MyCustField(serializers.CharField): """  Model               Serializer Field""" def to_representation(self, obj): """   Model       parse   Api""" return obj def to_internal_value(self, data): """        json    parse   Model""" return json.loads(data.encode('utf-8')) class UserSerializer(serializers.ModelSerializer): class Meta: model = User #       Model fields = ('id', 'username', 'mymodels') #       fields #          MyModel          ,    urls    name    #                  mymodels = serializers.HyperlinkedRelatedField( many=True, queryset=MyModel.objects.all(), view_name='model-detail' ) class MySerializer(serializers.ModelSerializer): options = MyCustField( max_length=1000, style={'base_template': 'textarea.html'}, ) class Meta: model = MyModel fields = ('id', 'owner', 'field', 'options') read_only_fields = ('owner',) #       field def create(self, validated_data): """   POST   """ #          model    owner validated_data['owner'] = self.context['request'].user return MyModel.objects.create(**validated_data) def update(self, instance, validated_data): """   PUT   """ instance.field = validated_data.get('field', instance.field) instance.save() return instance 

ViewSet
Serializers 를 정의 하면 viewset 을 쓰기 시작 할 수 있 습 니 다
사실 viewset 은 가장 쉬 운 부분 입 니 다. restframework 원생 은 네 가지 ViewSet 을 제공 합 니 다.ViewSet GenericViewSet
물려받다  GenericAPIView
ModelViewSet
자체 6 가지 방법 제공 list create retrieve update partial_update destroy
ReadOnlyModelViewSet
저 는 좋아해요.  ModelViewSet, 그리고 Premissions 로 권한 관리
# myproject/myapp/views.py

#! /usr/bin/env python
# -*- coding: utf-8
from __future__ import unicode_literals, absolute_import from django.contrib.auth.models import User from rest_framework import permissions, viewsets, renderers from rest_framework.decorators import ( permission_classes, detail_route ) from rest_framework.response import Response from .serializers import MySerializer, UserSerializer from .models import MyModel class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer #     ,       permission_classes = (permissions.IsAuthenticated,) class ModelViewSet(viewsets.ModelViewSet): queryset = MyModel.objects.all() serializer_class = MySerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly,) @detail_route(renderer_classes=[renderers.StaticHTMLRenderer]) def plaintext(self, request, *args, **kwargs): """    Api   """ model = self.get_object() return Response(repr(model)) 

나 는 ModelViewSet 에서 방법 plaintext, rest 를 사용자 정의 했다.프레임 워 크 에 서 는 사용자 정의 viewset 방법 에 두 가지 장식 기 를 제공 합 니 다.list_route detail_route
구별  list_route  매개 변수  pk (대응 list),  detail_route  포함 pk (대응 검색)
코드 를 보면 알 수 있 습 니 다.
@list_route(methods=['post', 'delete']) def custom_handler(self, request): pass @detail_route(methods=['get']) def custom_handler(self, request, pk=None): pass 

Filters
앞에서 serializers 와 viewset 에 따라 우 리 는 데이터 인터페이스 와 전 시 를 잘 제공 할 수 있 습 니 다.그러나 때때로 우 리 는 url 매개 변 수 를 통 해 데 이 터 를 정렬 하거나 여과 하 는 작업 을 해 야 한다. 이 를 위해 rest - framwork 는 filers 를 제공 하여 이 수 요 를 만족 시 켰 다.
전역 필터
settings 에서 전역 에 적용 할 filter 를 지정 할 수 있 습 니 다:
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',) } 

viewset filter
viewset 에 각각 filter 를 지정 할 수도 있 습 니 다. 방법 은 viewset 을 정의 할 때 이름 filter_backend 을 정의 하 는 것 입 니 다. 클래스 변수:
class UserListView(generics.ListAPIView): queryset = User.objects.all() serializer = UserSerializer filter_backends = (filters.DjangoFilterBackend,) 

기본 filter
rest - framework 는 몇 개의 원생 filter 를 제공 합 니 다.
SearchFilter
filter_backends = (filters.SearchFilter,) search_fields = ('username', 'email') #        

청구 하 다.  http://example.com/api/users?search=russell
OrderingFilter
filter_backends = (filters.OrderingFilter,) ordering_fields = ('username', 'email') 

청구 하 다.  http://example.com/api/users?ordering=account,-username
사용자 정의 filter
사용자 정의 filter 는 매우 간단 합 니 다. 정의 만 필요 합 니 다.  filter_queryset(self, request, queryset, view)  방법, 그리고 query set 를 되 돌려 주면 됩 니 다.
내 가 쓴 예 를 직접 붙 여 라.
class NodenameFilter(filters.BaseFilterBackend): """   nodename      [nodename]: NeiWang  """ def filter_queryset(self, request, queryset, view): nodename = request.QUERY_PARAMS.get('nodename') if nodename: return queryset.filter(nodename=nodename) else: return queryset 

매개 변수 가 잘못 일치 하면 이상 을 던 지 려 면 APIError 를 사용자 정의 할 수도 있 습 니 다. 예 를 들 어:
from rest_framework.exceptions import APIException


class FilterError(APIException): status_code = 406 default_detail = 'Query arguments error!' 

그리고 viewset 에서 바로 던 져 요.  raise FilterError  됐다.
Premissions
말 그대로 권한 관리 입 니 다. ViewSet 에 권한 을 설정 하고 premissions 를 사용 하면 서로 다른 등급 의 권한 을 편리 하 게 설정 할 수 있 습 니 다.
전역 권한 제어 ViewSet 의 권한 제어 Method 권한 Object 의 권한 premission 에 의 해 차단 되 는 요청 은 다음 과 같은 결 과 를 얻 을 수 있 습 니 다.
사용자 가 로그 인 했 지만 premissions 에 의 해 제한 되 어 돌아 갑 니 다.  HTTP 403 Forbidden
사용자 가 로그 인하 지 않 으 면 premissions 제한 으로 되 돌아 갑 니 다.  HTTP 401 Unauthorized
기본 권한
rest_framework 에서 7 가지 권한 을 제공 합 니 다.AllowAny  # 무제 한 IsAuthenticated  # 로그 인 사용자 IsAdminUser  # 관리자 IsAuthenticatedOrReadOnly  # 로그 인 하지 않 은 사용자 만 읽 기 DjangoModelPermissions  # 다음은 모두 Django 의 Model Premissions 에 따 른 것 입 니 다.DjangoModelPermissionsOrAnonReadOnly DjangoObjectPermissions
전역 권한 제어
settings. py 에서 전역 기본 권한 을 설정 할 수 있 습 니 다.
# settings.py

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.AllowAny', ), } 

ViewSet 의 권한
설정 가능  permission_classes  viewset 에 권한 을 설정 하 는 클래스 속성 입 니 다. restframework 는 원본 그룹의 모든 premission 을 검사 합 니 다. 모두 통과 해 야 합 니 다.
class UserViewSet(viewsets.ReadOnlyModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer #     ,      permission_classes = (permissions.IsAuthenticated,) 

사용자 정의 권한
premissions 는 매우 편리 하 게 맞 출 수 있 습 니 다. 예 를 들 어 저 는 owner 편집 만 허용 하 는 권한 을 스스로 썼 습 니 다.
# myproject/myapp/premissions.py

#! /usr/bin/env python
# -*- coding: utf-8
from __future__ import unicode_literals, absolute_import from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): def has_permission(self, request, view): """            """ if request.method in permissions.SAFE_METHODS: return True def has_object_permission(self, request, view, obj): """            ,   True     """ #          if request.method in permissions.SAFE_METHODS: return True #                owner return obj.owner == request.user 

urls & routers
# myproject/myapp/urls.py

#! /usr/bin/env python
# -*- coding: utf-8
from __future__ import unicode_literals, absolute_import from django.conf.urls import url, patterns, include from rest_framework.routers import DefaultRouter from . import views # as_view      view #           `{Http Method: View Method}` user_detail = views.UserViewSet.as_view({'get': 'retrieve'}) user_list = views.UserViewSet.as_view({'get': 'list', 'post': 'create'}) # plaintext         ,           modal_plain = views.ModelViewSet.as_view({'get': 'plaintext'}) model_detail = views.ModelViewSet.as_view({'get': 'retrieve', 'post': 'create'}) model_list = views.ModelViewSet.as_view({'get': 'list', 'post': 'create'}) # router           Api Root    router = DefaultRouter() router.register(r'models', views.ModelViewSet) router.register(r'users', views.UserViewSet) #       views     urls   urlpatterns = patterns( '', url(r'^', include(router.urls)), # Api Root url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), url(r'^models/(?P[0-9]+)/$', model_detail, name='model-detail'), url(r'^models/(?P[0-9]+)/plain/$', modal_plain, name='model-plain'), url(r'^models/$', model_list, name='model-list'), url(r'^users/$', user_list, name='user-list'), url(r'^users/(?P[0-9]+)/$', user_detail, name='user-detail'), ) 

시간 이 촉박 해서 이런 것들 을 소개 하고 나중에 시간 이 나 면 Django 에서 JWT 를 신분증 으로 사용 하 는 것 을 소개 합 니 다.다음은 효과 도 입 니 다.
Api Root
Users

좋은 웹페이지 즐겨찾기