django rest_framework入门二-序列化

在前一节中,我们已经粗略地介绍了rest_framework的作用之一序列化,下面我们将详细探究序列化的使用。

1.新建一个app snippets

python manage.py startapp snippets

更新配置文件tutorial/settings.py,注册到APPS

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

2.创建Model,定义实体
编辑snippets/models.py,添加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())


# Create your models here.
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
python manage.py migrate

3.创建Serializer类,提供序列化,反序列化方法
新建serializers.py,代码如下:

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


class SnippetSerializer(serializers.Serializer):
    pk = 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')
    created = serializers.DateTimeField(read_only=True)

SnippetSerializer定义了序列化/反序列化的字段,包括字段的类型,范围,不符合的字段值将无法完成序列化/反序列化
Serializer类,有一个save()方法,用来将json格式数据,新增或修改对象。原理如下:

class SnippetSerializer(serializers.Serializer):
    pk = 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')
    created = serializers.DateTimeField(read_only=True)

    def create(self, validated_data):
        return Snippet.objects.create(**validated_data)

    def update(self, instance, 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

4.Serializer类的使用
新增Snippet对象

from snippets.models import Snippet


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

使用Serializer类序列化Snippet对象

# Create your tests here.
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer


snippet = Snippet.objects.first()

serializer = SnippetSerializer(snippet)
print(type(serializer.data))
print(serializer.data)

运行结果:

返回json格式数据

使用Serializer类反序列化Snippet对象

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer


data = {
    'code': 'print "hello, python"\n'
}
serializer = SnippetSerializer(data=data)
if serializer.is_valid():
    snippet = serializer.save()
    print(snippet)
else:
    print(serializer.error_messages)

运行结果:

返回Snippet对象

5.ModelSerializer代替Serializer
Serializer和Model有太多重复的地方,因此有了ModelSerializer,代码示例如下:

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


class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = ("id", "title", "code", "linenos", "language", "style", "created")

运行结果:

ModelSerializer没有使用任何黑科技,实质和Serializer类一样,也是根据Model创建Serializer的过程

6.使用serializer类编写视图
编辑views.py,代码示例如下:

import json

from django.shortcuts import render
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer


# Create your views here.
@csrf_exempt
def snippet_list(request):
    if request.method == 'GET':
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True) #返回字典列表
        result_type = type(serializer.data)
        result = json.dumps(serializer.data) # 字典转化为json字符串
        return HttpResponse(result)

    if request.method == 'POST':
        data = request.body
        data = json.loads(data) # json字符串转字典
        serializer = SnippetSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            result = serializer.data
        else:
            result = {
                'status': "failed"
            }
        result = json.dumps(result) # 字典转化为json字符串
        return HttpResponse(result)

csrf_exempt:允许跨域访问
snippet_list: GET--访问Snippet列表
POST--新增Snippet实体

编辑tutorial/urls.py,加入访问snippet地址

from snippets import views

urlpatterns = [
    url(r'^snippets/$', views.snippet_list),
    url(r'^admin/', admin.site.urls),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

运行结果:
post访问

get访问

posted on 2018-05-22 16:50  迪米特  阅读(551)  评论(0编辑  收藏  举报

导航