Django REST framework 官方教程学习笔记

本笔记以 Django REST framework 官方教程为基础,使用截至目前(2021年12月)最新版本的 Python、Django 以及 Django REST framework,因此代码会略有不同。

官方教程地址

https://www.django-rest-framework.org/tutorial/1-serialization/

开发环境:

  • Win10
  • Windows Terminal
  • Python 3.10.1
  • Django 4.0
  • djangorestframework 3.12.4

1. Serialization 序列化

1.1 创建虚拟环境并激活

为练习项目创建一个新的虚拟环境:

python3 -m venv test_env

激活虚拟环境:

./test_env/Scripts/Activate.ps1

test_env 中安装 Django、Django REST framework 和 pygments:

pip install django
pip install djangorestframework
pip install pygments

1.2 创建一个 Django 项目并在项目中创建一个 app

django-admin startproject rest_tutorial
cd .\rest_tutorial\
python manage.py startapp snippets

INSTALLED_APPS 中添加 snippetsrest_framework:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'snippets.apps.SnippetsConfig'
]

1.3 创建模型

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

报错:Invalid template library specified. ImportError raised when trying to load 'rest_framework.templatetags.rest_framework': No module named 'pytz'

根据报错,安装 pytz:

pip install pytz

再次执行迁移命令:

python manage.py makemigrations snippets
python manage.py migrate

1.4 创建序列化器

在 app snippets 的目录下,创建一个 serializers.py 文件

from rest_framework import serializers
from .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'})
    line_numbers = 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.line_numbers = validated_data.get('line_numbers', instance.line_numbers)
        instance.language = validated_data.get('language', instance.language)
        instance.style = validated_data.get('style', instance.style)
        instance.save()
        return instance

序列化器实例 SnippetSerializer 的前半部分定义了哪些字段需要进行序列化和反序列化;create()update() 方法定义了在调用 serializer.save() 时如何创建和修改完整的 Snippet 实例。

序列化器类与 Django 表单类非常相似,并且在各个字段上包含类似的验证标志,例如 requiredmax_lengthdefault。在某些情况下,字段标志还可以控制序列化的显示方式。上面的 {'base_template': 'textarea.html'} 标志相当于在 Django Form 类上使用 widget=widgets.Textarea

1.5 在 Django shell 中测试序列化器

启动 Django shell:

python manage.py shell

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

上述命令添加了两个 snippet 实例,下面使用 SnippetSerializer 来序列化 snippet

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

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

要退出 Django shell ,可以执行以下命令:

quit()

1.6 使用 ModelSerializers 类重构序列化器

前面写的序列化器 SnippetSerializer 中很多内容跟 Snippet 模型都是重复的,下面使用 ModelSerializers 类对其进行重构:

还有 82% 的精彩内容
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
支付 ¥59.90 继续阅读

推荐阅读更多精彩内容