Django REST framework 를 이용 하여 RESTful API 를 작성 합 니 다.
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
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.