1. 程式人生 > >[Django rest-framework] 1-Serialization

[Django rest-framework] 1-Serialization

www. spa key blog urn allow max pytho led

個人粗淺的理解,歡迎批評指正

什麽是序列化?

  後端任務無非對數據庫的增查刪改,操作數據庫無非操作字段,序列化可以讓我們輕松的對數據庫增(serializer.create)改(serilaizer.update)的同時不用擔心提交的key/value是否合法(serializer.is_valid),並輕松的將dict 格式轉為更通用的json格式(JSONRenderer)

什麽是反序列化?

  將json轉為JSONParser().parse(stream)可序列化的dict(serializer(data=data))

跟著教程走一波

先安裝一下virtualenv

新建一個虛擬環境env

進入env虛擬環境

sudo apt-get install virtualenv
virtualenv env
source env/bin/activate

離開虛擬環境:deactivate

ps:如果使用pycharm IDE,在file-settings-Project:XXX-Project Interpreter,將項目解釋器設置為虛擬環境中安裝的python

在我們的虛擬環境中安裝其他所需庫

pip install django
pip install djangorestframework
pip install pygments # 用來高亮代碼的庫

創建項目,創建app

cd ~
django-admin.py startproject tutorial
cd tutorial

python manage.py startapp snippets

記得settings.INSTALLED_APPS中添加剛才創建的app

INSTALLED_APPS = (
    ...
    ‘rest_framework‘,
    ‘snippets.apps.SnippetsConfig‘,
)

django 創建一個django模型

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

有沒有菜雞跟我一樣才發現,原來從模型這裏就可以限制字段的可選值(choices)

Meta元類中的ordering是指quarySet排序按’created‘字段來

django的orm

操作下數據庫

python manage.py makemigrations snippets
python manage.py migrate

重點到了,新建一個serializers.py 文件,並創建我們的序列化類

from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES


class SnippetSerializer(serializers.Serializer):
    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

create和update是必須在子類中實現的方法,因為調用serializer.save()方法會用到他們

serializer類和django的model類很相似,可以在聲明的時候限制字段的屬性

接下來看看怎麽使用序列化類

先打開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"\n‘)
snippet.save()

snippet = Snippet(code=‘print "hello, world"\n‘)
snippet.save()

接著:

1:序列化

serializer = SnippetSerializer(snippet)
serializer.data
# {‘id‘: 2, ‘title‘: u‘‘, ‘code‘: u‘print "hello, world"\n‘, ‘linenos‘: False, ‘language‘: u‘python‘, ‘style‘: u‘friendly‘}

2:轉json

content = JSONRenderer().render(serializer.data)
content
# ‘{"id": 2, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}‘

3:轉dict

from django.utils.six import BytesIO

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

4:反序列化

serializer = SnippetSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# OrderedDict([(‘title‘, ‘‘), (‘code‘, ‘print "hello, world"\n‘), (‘linenos‘, False), (‘language‘, ‘python‘), (‘style‘, ‘friendly‘)])
serializer.save()
# <Snippet: Snippet object>

5:支持序列化多個數據

serializer = SnippetSerializer(Snippet.objects.all(), many=True)
serializer.data
# [OrderedDict([(‘id‘, 1), (‘title‘, u‘‘), (‘code‘, u‘foo = "bar"\n‘), (‘linenos‘, False), (‘language‘, ‘python‘), (‘style‘, ‘friendly‘)]), OrderedDict([(‘id‘, 2), (‘title‘, u‘‘), (‘code‘, u‘print "hello, world"\n‘), (‘linenos‘, False), (‘language‘, ‘python‘), (‘style‘, ‘friendly‘)]), OrderedDict([(‘id‘, 3), (‘title‘, u‘‘), (‘code‘, u‘print "hello, world"‘), (‘linenos‘, False), (‘language‘, ‘python‘), (‘style‘, ‘friendly‘)])]

看到這裏感覺序列化就是將form對象轉為dict格式,將quaryset轉為OrderedDict

下節學習一下,正真更通用的ModelSerializers

參考資料:http://www.django-rest-framework.org/tutorial/1-serialization/#tutorial-1-serialization

[Django rest-framework] 1-Serialization