创建项目及相应app

django-admin.py startproject tutorial
python manage.py startapp snippets

并将rest_frameworksnippets添加到settings.pyINSTALLED_APPS中。

INSTALLED_APPS = [
    ...
    "rest_framework",
    "snippets"
]

创建模型

# 需要先安装pygments库
from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles


# 获取pygments支持的所有语言的此法分析程序
LEXERS = [item for item in get_all_lexers() if item[1]]
# 获取pygments支持的所有语言列表
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
# 获取pygments支持的所有格式化风格列表
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

创建序列化类

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=True, 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):
        """
        给验证过的数据创建并返回一个新的实例
        """
        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

序列化器第一部分定义了获取序列化/反序列化的字段。create()和update()方法定义了在调用serializer.save()时如何创建和修改完整实例。
序列化器类与Django Form类非常的相似,并在各种字段中包含类似的验证标志。
字段标志还可以控制serializer在某些情况下的显示,比如渲染HTML的时候,{'base_template': 'textarea.html'} 标志等同于在 Django Form 类中使用 widget=widgets.Textarea

使用Serializers

以下示例将在Django shell中

python manage.py shell

创建snippet实例

>>> 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()

查看实例

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

将模型示例转换为Python原生数据类型,要完成序列化过程,我们将数据渲染成json。

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

反序列化

>>> from django.utils.six import BytesIO
>>> stream = BytesIO(content)
>>> data = JSONParser().parse(stream)
>>> data
{'id': 2, 'title': '', 'code': "print 'hello, world'\n", 'linenos': False, 'language': 'python', 'style': 'friendly'}

将原生数据类型恢复成正常的对象实例

>>> 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()
<Snippet: Snippet object (3)>

序列化查询集代替模型实例

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

使用ModelSerializers

上面的SnippetSerializer类中重复了很多Snippet模型中的信息。就像Django的提供了Form类和ModelForm类一样,REST framework同样也提供了Serializer类和ModelSerializer类。

创建新的SnippetSerializer

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

ModelSerializer只是创建序列化器类的快捷方式,不会额外做其他任何特别的事情:

  • 自动确定一组字段。
  • 默认简单实现的create()和update()方法。

编写Django视图

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


@csrf_exempt
def snippet_list(request):

    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_exempt
def snippet_detail(request, pk):
    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)

urls.py

from django.urls import path
from snippets import views


urlpatterns = [
    path("snippets/", views.snippet_list),
    path("snippet/<int:pk>/", views.snippet_detail)
]

并且根目录下的urls.py的同样需要进配置

from django.conf.urls import url, include

urlpatterns = [
    ...
    url(r'^', include('snippets.urls')),
]
0条评论

相关推荐

django教程

r

Django 2019-05-20 10:53:53

Celery

celery学习资料

Django 2019-05-25 18:41:55

django教程入门

适合django新人使用的学习手册

Django 2019-07-01 14:28:04

django实用资料

django项目从0到1自己总结的实用的资料,大部分常用的功能这里都有

Django 2019-05-08 18:21:34