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 继续阅读
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容