Django+React全棧開發:序列化器

REST framework

咱們繼續以前的內容,讓咱們先進入項目文件夾react_drf,激活虛擬環境,並安裝REST frameworkhtml

$ source venv/bin/activate
// 激活後命令提示符前面會出現(venv)
(venv) $ pip install djangorestframework
Django REST framework is a powerful and flexible toolkit for building Web APIs.

官方介紹:Django REST framework是一個用於構建WEB API的強大而靈活的工具。前端

還記得在上一篇文章中提到的RESTful API嗎?此次咱們就來試試使用REST framework這個庫來改造咱們以前寫的程序。python

安裝完成後,記獲得項目文件夾backend/backend/settings.py文件中註冊:react

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework', # 加上這個
    'article.apps.ArticleConfig',
]

擴展模型

打開咱們的backend/article/models.py文件,本來的內容有點少,咱們首先把這個模型擴展一下:shell

from django.db import models


class Article(models.Model):
    title = models.CharField(max_length=50)
    body = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    
    class Meta:
        ordering = ('-created',)

注意咱們定義的繼承了models.Model的類Article,與數據庫中的有對應關係,能夠看到這個類的不一樣屬性分別是不一樣的對象示例,它們對應了數據庫中的的不一樣,而且表明了不一樣的數據類型。數據庫

createdupdated經過將兩個不一樣的參數設置爲True實現了自動保存建立時間與最後修改時間的功能。django

這裏在元類裏定義了以建立時間降序排序,注意ordering應該是一個元組,因此別忘了逗號,後端

好啦,還記得每次更改模型後要作什麼?session

(venv)  $ python manage.py makemigrations article 
Migrations for 'article':
  article/migrations/0001_initial.py
    - Create model Article
(venv)  $ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, article, auth, authtoken, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  ……
  Applying sessions.0001_initial... OK

如今遷移完成了,可是如今不急着去寫視圖和模板,咱們要開始製做本身的RESTful API。app

序列化

還記得以前提過,REST的意思是表現層狀態轉換,咱們須要有一個工具來對模型進行序列化與反序列化,通俗的講法序列化就是將語言中的對象轉化爲能夠存儲或傳輸的形式,反序列化就是反過來的過程。

在先後端分離模式的開發中,因爲先後端語言每每是不一樣的,例如後端Java,前端JavaScript,或者有移動端的Kotlin,每每須要一種較爲通用的格式,JSON就是一個不錯的選擇。

好了,開始行動吧,在article文件夾中新建一個serializers.py文件:

# article/serializers.py
class ArticleSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    title = serializers.CharField(required=True, max_length=50)
    body = serializers.CharField(required=True)
    created = serializers.DateTimeField(read_only=True)
    updated = serializers.DateTimeField(read_only=True)

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

    def update(self, instance, validated_data):
        instance.title = validated_data.get('title', instance.title)
        instance.body = validated_data.get('body', instance.title)
        instance.save()
        return instance

因爲TextFieldDjango定義的針對大文本內容的擴展字段,因此在rest_framework中仍是隻能用CharField來序列化。覆寫createupdate方法來定義調用serializer.save()時的行爲。參數required=True表示必填,read_only=True表示只讀。

shell

Django爲咱們提供了一個交互式的調試環境,輸入命令python manage.py shell命令,進入交互環境。

先來看看序列化一個Article實例:

>>> from article.models import Article
>>> from article.serializers import ArticleSerializer
>>> from rest_framework.renderers import JSONRenderer
>>> from rest_framework.parsers import JSONParser
>>> article = Article(title="React", body="React is good")
>>> article.save()
>>> serializer = ArticleSerializer(article)
>>> serializer.data
{'id': 2, 'title': 'React', 'body': 'React is good', 'created': '2020-03-21T21:19:31.732703', 'updated': '2020-03-21T21:19:31.732728'}

以前經過序列化器將實例序列化爲Python內置的字典類型,如今看看將其轉爲JSON

>>> content = JSONRenderer().render(serializer.data)
>>> content
b'{"id":2,"title":"React","body":"React is good","created":"2020-03-21T21:19:31.732703","updated":"2020-03-21T21:19:31.732728"}'

反序列化與上面相似,但步驟相反:

>>> import io
>>> stream = io.BytesIO(content)
>>> data = JSONParser().parse(stream)
>>> serializer = ArticleSerializer(data=data)
>>> serializer.is_valid()
True
>>> serializer.validated_data
OrderedDict([('title', 'React'), ('body', 'React is good')])
>>> serializer.save()
<Article: Article object (3)> # 這裏爲3是由於我最初存了一個數據

ModelSerializer

REST framework爲咱們提供了一個更爲簡潔的編寫序列化器的方式:

# 修改本來的ArticleSerializer類
class ArticleSerializer(serializers.ModelSerializer):

    class Meta:
        model = Article
        fields = ['id', 'title', 'body', 'created', 'updated']

能夠在交互模式下看看:

>>> from article.serializers import ArticleSerializer
>>> serializer = ArticleSerializer()
>>> print(repr(serializer))
ArticleSerializer():
    id = IntegerField(label='ID', read_only=True)
    title = CharField(max_length=50)
    body = CharField(style={'base_template': 'textarea.html'})
    created = DateTimeField(read_only=True)
    updated = DateTimeField(read_only=True)
>>>

ModelSerializer幫咱們自動生成了所需的字段,而且擁有createupdate方法的默認實現。這是官方爲咱們提供的實現一個序列化器的快捷方式。注意到這裏還對模型中的TextField類型的body作了特殊處理,定義了其渲染成HTML時的格式。

若是你對原生Django的表單熟悉,你會發現這個Serializer與原生的Form很是類似。

總結

如今咱們熟悉了序列化反序列化,在下一篇文章中,咱們將爲咱們的API編寫一個新的視圖(View)

掃碼關注公子政的宅平常第一時間查看最新推送:

公子政的宅平常

相關文章
相關標籤/搜索