Django-REST의 1:serializers 서열기 - 번역 및 자신의 학습 노트(업데이트 보완 중...)

자습서 1: 서열화


소개하다.


이 자습서는 웹 API를 강조 표시하는 간단한 붙여넣기 코드를 만드는 방법에 대해 설명합니다.가는 길에 REST 프레임워크를 구성하는 다양한 구성 요소를 소개하고 모든 것이 어떻게 융합되는지 전면적으로 이해할 것이다.
이 강좌는 상당히 깊기 때문에 시작하기 전에 쿠키 하나와 당신이 가장 좋아하는 양조 한 잔을 받아야 합니다.빠른 탐색만 하고 싶으면 빠른 입문 문서로 바꾸십시오.
주의: 이 강좌의 코드는 GitHub의tomchristie/rest-framework-tutorial 저장소에서 찾을 수 있습니다.완성된 실시도 온라인으로 샌드박스 버전으로 테스트를 진행한 것으로 보인다.

새로운 환경을 만들다


우리가 어떤 일을 하기 전에, 우리는virtualenv를 사용하여 새로운 가상 환경을 만들 것이다.이것은 우리의 가방 설정이 우리가 진행하고 있는 다른 프로젝트와 양호한 격리를 유지하도록 확보할 것이다.
virtualenv env
source env/bin/activate

현재 우리는virtualenv 환경에서 우리의 가방을 설치할 수 있습니다.
pip install django
pip install djangorestframework
pip install pygments  # We'll be using this for the code highlighting

주의:virtualenv 환경을 언제든지 종료하려면 deactivate만 입력하십시오.더 많은 정보는virtualenv 문서를 참조하십시오.

입문


네, 인코딩을 받을 준비가 되어 있습니다.시작하려면 새 프로젝트를 만들어서 처리합니다.
cd ~
django-admin.py startproject tutorial
cd tutorial

일단 완성되면 간단한 웹 API를 만드는 데 사용할 프로그램을 만들 수 있습니다.
python manage.py startapp snippets

우리는 우리의 새로운 snippets 응용 프로그램과 rest_framework 응용 프로그램INSTALLED_APPS을 추가해야 한다.tutorial/settings.py 파일을 편집합니다.
INSTALLED_APPS = (
    ...
    'rest_framework',
    'snippets.apps.SnippetsConfig',
)

만약 당신이 사용한 Django<1.9라면 교환snippets.apps.SnippetsConfig이 필요합니다snippets.
네, 준비 다 됐습니다.

사용할 수 있는 모델 생성하기


본 강좌의 목적을 위해서, 우리는 먼저 코드 세션을 저장하는 간단한 모델을 만들 것입니다.파일 편집Snippet을 계속합니다.주의: 좋은 프로그래밍 실천은 평론을 포함합니다.이 강좌 코드의 저장소 버전에서 찾을 수 있지만, 코드 자체에 전념하기 위해 이 강좌 코드를 무시합니다.
from django.db import models
from pygments.lexers import get_all_lexers   #  引入高亮显示语法规则
from pygments.styles import get_all_styles   #  引入显示风格

LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted((item, item) for item in get_all_styles())


class Snippet(models.Model):
    created = models.DateTimeField(auto_now_add=True)   #         
    title = models.CharField(max_length=100, blank=True, default='') #    
    code = models.TextField()  #             
    linenos = models.BooleanField(default=False)  #        
    language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)   #        
    style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)  #        

    class Meta:     #                 
        ordering = ('created',)   #          

우리는 또한 우리의 코드 세그먼트 모델을 위해 초기 이동을 만들고 데이터베이스를 처음으로 동기화해야 한다.
python manage.py makemigrations snippets
python manage.py migrate

Serializer 클래스 만들기


우리가 웹 API를 사용하기 시작해야 할 첫 번째 일은 코드 세션의 실례를 서열화하고 반서열화하는 방법snippets/models.py을 제공하는 것이다.우리는 Django 폼과 매우 비슷한 서열화기를 성명함으로써 이 점을 할 수 있다.json명명된 디렉터리에 파일을 만들고 snippets다음 내용을 추가합니다.
from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES


class SnippetSerializer(serializers.Serializer):  #           ,   models     
    id = serializers.IntegerField(read_only=True)
    title = serializers.CharField(required=False, allow_blank=True, max_length=100)
    code = serializers.CharField(style={'base_template': 'textarea.html'})
    linenos = serializers.BooleanField(required=False)
    language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')
    style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')

    def create(self, validated_data):    #         ,      
        """
        Create and return a new `Snippet` instance, given the validated data.
        """
        return Snippet.objects.create(**validated_data)

    def update(self, instance, validated_data):   #         ,      
        """
        Update and return an existing `Snippet` instance, given the validated data.
        """
        instance.title = validated_data.get('title', instance.title)
        instance.code = validated_data.get('code', instance.code)
        instance.linenos = validated_data.get('linenos', instance.linenos)
        instance.language = validated_data.get('language', instance.language)
        instance.style = validated_data.get('style', instance.style)
        instance.save()
        return instance

서열화기 클래스의 첫 번째 부분은 서열화/반서열화된 필드를 정의합니다.이 serializers.pycreate() 방법은 실례가 어떻게 완전히 성숙한 창설 또는 수정 시 호출되는지 정의한다update()갑직렬류는 Djangoserializer.save()류와 매우 유사하며 각 필드와 유사한 검증 표시를 포함한다. 예를 들어 Form,requiredmax_length.
필드 플래그는 HTML로 렌더링할 때 Serial을 표시하는 방법과 같은 경우에도 제어할 수 있습니다.default 위의 표지는 {'base_template': 'textarea.html'}Djangowidget=widgets.Textarea류에서 사용하는 것과 같다.이것은 탐색 가능한 API를 표시하는 방법을 제어하는 데 특히 유용하며, 본 강좌의 뒤에 있을 것입니다.
우리는 실제로도 Form 과정을 사용하여 자신의 시간을 절약할 수 있다. 우리는 잠시 후에 볼 수 있지만, 지금은 우리의 서열화기 정의를 유지할 것이다.

Serial 사용


우리가 더 깊이 이해하기 전에, 우리는 우리의 새로운 Serializer 종류를 잘 사용할 것이다.Django shell로 들어갑니다.
python manage.py shell

좋습니다. 일단 몇 개의 가져오기가 있으면, 코드 세션을 만들어서 처리하겠습니다.
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser

snippet = Snippet(code='foo = "bar"
'
) # model ,code snippet.save() snippet = Snippet(code='print "hello, world"
'
) snippet.save()

우리는 지금 몇 개의 실례를 가지고 놀 수 있다.우리는 이 실례들 중의 하나를 서열화하는 것을 보았다.
serializer = SnippetSerializer(snippet)
serializer.data
# {'id': 2, 'title': u'', 'code': u'print "hello, world"
', 'linenos': False, 'language': u'python', 'style': u'friendly'}

이 때, 우리는 모델 실례를 Python 본체 데이터 형식으로 변환합니다.서열화 과정을 완성하기 위해서 우리는 데이터를 ModelSerializer로 변환할 것이다.
content = JSONRenderer().render(serializer.data)
content
# '{"id": 2, "title": "", "code": "print \\"hello, world\\"\
", "linenos": false, "language": "python", "style": "friendly"}'

반서열화는 유사하다.우선 우리는 하나의 흐름을 Python 본체의 데이터 형식으로 해석할 것이다.
from django.utils.six import BytesIO

stream = BytesIO(content)
data = JSONParser().parse(stream)

...그리고 우리는 이 컴퓨터의 데이터 형식을 완전히 채워진 대상의 실례로 복원할 것이다.
serializer = SnippetSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# OrderedDict([('title', ''), ('code', 'print "hello, world"
'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])
serializer.save() #

API 및 양식 사용에 주의하십시오.직렬기를 사용하는 보기를 작성하기 시작하면 유사성이 더욱 뚜렷해질 것입니다.
우리도 모델 실례가 아닌 서열화된 조회 집합을 만들 수 있다.이를 위해, 우리는 jsonserializer 매개 변수에 로고를 추가해야 합니다.
serializer = SnippetSerializer(Snippet.objects.all(), many=True)
serializer.data
# [OrderedDict([('id', 1), ('title', u''), ('code', u'foo = "bar"
'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', u''), ('code', u'print "hello, world"
'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', u''), ('code', u'print "hello, world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]

ModelSerializers 사용


우리의 many=True 과정은 SnippetSerializer 모델에 포함된 대량의 정보를 복제하고 있다.만약 우리가 우리의 코드를 더욱 간결하게 유지할 수 있다면, 그것은 매우 좋을 것이다.
Django가 제공하는 Snippet클래스와 Form클래스와 같은 방식으로 REST 프레임워크는 ModelForm클래스와 Serializer클래스를 포함한다.
사용 ModelSerializer 클래스를 사용하여 우리의serializer를 재구성하는 것을 살펴봅시다.ModelSerializer 이 파일을 다시 열고 snippets/serializers.py 이하로 대체합니다.
class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = ('id', 'title', 'code', 'linenos', 'language', 'style')

서열화기가 가지고 있는 좋은 속성은 그 표현을 인쇄해서 서열화기 실례의 모든 필드를 검사할 수 있다는 것이다.Django 셸SnippetSerializer을 열고 다음을 시도합니다.
from snippets.serializers import SnippetSerializer
serializer = SnippetSerializer()
print(repr(serializer))
# SnippetSerializer():
#    id = IntegerField(label='ID', read_only=True)
#    title = CharField(allow_blank=True, max_length=100, required=False)
#    code = CharField(style={'base_template': 'textarea.html'})
#    linenos = BooleanField(required=False)
#    language = ChoiceField(choices=[('Clipper', 'FoxPro'), ('Cucumber', 'Gherkin'), ('RobotFramework', 'RobotFramework'), ('abap', 'ABAP'), ('ada', 'Ada')...
#    style = ChoiceField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful')...

중요한 것은 python manage.py shell클래스는 특별히 신기한 일을 하지 않고 서열화기 클래스를 만드는 단축키일 뿐이라는 것을 기억해야 한다.
자동으로 결정되는 필드 세트
간단한 기본 구현ModelSerializercreate() 방법.

Dell Serializer를 사용하여 정상적인 Django 뷰 작성


새로운 Serializer 클래스를 사용하여 API 보기를 작성하는 방법을 살펴보겠습니다.현재는 REST 프레임워크의 다른 기능을 사용하지 않습니다. 보기를 일반적인 Django 보기로 작성하기만 하면 됩니다.update() 파일을 편집하고 다음을 추가합니다.
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer

우리의 API는 기본적으로 하나의 보기로 모든 기존 세션을 열거하거나 새로운 세션을 만들 수 있습니다.
@csrf_exempt
def snippet_list(request):
    """
    List all code snippets, or create a new snippet.
    """
    if request.method == 'GET':
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return JsonResponse(serializer.data, safe=False)

    elif request.method == 'POST':
        data = JSONParser().parse(request)
        serializer = SnippetSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=201)
        return JsonResponse(serializer.errors, status=400)

CSRF 토큰이 없는 클라이언트가 이 보기에서 POST를 진행하기를 원하기 때문에 보기를 snippets/views.py로 표시해야 합니다.이것은 당신이 일반적으로 하고 싶은 일이 아니다. REST 프레임워크 보기는 실제적으로 이것보다 더 명확한 행동을 하지만, 지금은 우리의 목적에 사용될 것이다.
단일 코드 세그먼트에 대응하는 보기가 필요합니다. 검색, 업데이트, 삭제에 사용할 수 있습니다.
@csrf_exempt
def snippet_detail(request, pk):
    """
    Retrieve, update or delete a code snippet.
    """
    try:
        snippet = Snippet.objects.get(pk=pk)
    except Snippet.DoesNotExist:
        return HttpResponse(status=404)

    if request.method == 'GET':
        serializer = SnippetSerializer(snippet)
        return JsonResponse(serializer.data)

    elif request.method == 'PUT':
        data = JSONParser().parse(request)
        serializer = SnippetSerializer(snippet, data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors, status=400)

    elif request.method == 'DELETE':
        snippet.delete()
        return HttpResponse(status=204)

마지막으로 우리는 이 관점들을 연결시켜야 한다.생성csrf_exempt 파일:
from django.conf.urls import url
from snippets import views

urlpatterns = [
    url(r'^snippets/$', views.snippet_list),
    url(r'^snippets/(?P[0-9]+)/$', views.snippet_detail),
]
snippets/urls.py 파일에 루트urlconf를 연결해서 세션 프로그램의 URL을 포함해야 합니다.
from django.conf.urls import url, include

urlpatterns = [
    url(r'^', include('snippets.urls')),
]

주의해야 할 것은 우리가 아직 정확하게 처리하지 못한 몇 가지 변두리 사례이다.만약 우리가 형식 오류tutorial/urls.py를 보내거나, 요청이 보기에서 처리하지 않는 방법을 사용한다면, 우리는 최종적으로 500개의 서버 오류 응답이 발생할 것이다.하지만 지금 이렇게 해요.

웹 API에서의 첫 번째 시도 테스트


현재 우리는 우리의 코드 세션을 서비스하는 예시 서버를 시작할 수 있다.
케이스 종료...
quit()

...Django의 개발 서버를 시작합니다.
python manage.py runserver

Validating models...

0 errors found
Django version 1.11, using settings 'tutorial.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

다른 터미널 창에서 서버를 테스트할 수 있습니다.
우리는curl이나httpie를 사용하여 API를 테스트할 수 있습니다.Httpie는 Python으로 작성된 사용자 친화적인 http 클라이언트입니다.저희가 설치할게요.
pip를 사용하여 httpie를 설치할 수 있습니다.
pip install httpie

마지막으로 모든 세션의 목록을 얻을 수 있습니다.
http http://127.0.0.1:8000/snippets/

HTTP/1.1 200 OK
...
[
  {
    "id": 1,
    "title": "",
    "code": "foo = \"bar\"
"
, "linenos": false, "language": "python", "style": "friendly" }, { "id": 2, "title": "", "code": "print \"hello, world\"
"
, "linenos": false, "language": "python", "style": "friendly" } ]

또는 ID를 참조하여 특정 코드 세그먼트를 가져올 수 있습니다.
http http://127.0.0.1:8000/snippets/2/

HTTP/1.1 200 OK
...
{
  "id": 2,
  "title": "",
  "code": "print \"hello, world\"
"
, "linenos": false, "language": "python", "style": "friendly" }

마찬가지로, 웹 브라우저에서 이 URL에 접근해서 같은 json을 표시할 수 있습니다.

우리 지금 어디야?


우리는 지금까지 잘했다. 우리는 서열화된 API를 가지고 있는데, Django의FormsAPI와 일반적인 Django 보기와 매우 비슷하다.
우리의 API 보기는 현재 특별한 점이 없습니다. json 응답을 제공하는 것 외에, 우리가 여전히 정리하고자 하는 가장자리 상황을 잘못 처리하는 것도 있지만, 이것은 잘 작동하는 웹 API입니다.

좋은 웹페이지 즐겨찾기