Django(46)drf序列化類的使用(ModelSerializer)

Silent丿丶黑羽發表於2021-06-06

前言

我們上篇文章使用到了Serializer類,可能有小夥伴說太過複雜,那麼本篇就為大家帶來更加簡便的序列化類ModelSerializer
 

ModelSerializer

先來看下ModelSerializer的程式碼結構如下:
Django(46)drf序列化類的使用(ModelSerializer)
可以看到ModelSerializer是繼承自Serializer,官方是這麼介紹到的

ModelSerializer只是一個常規的Serializer,只是做了以下事情

  • 將自動填充一組預設欄位
  • 將自動填充一組預設驗證程式
  • 提供了預設的.create().update()實現

我們將之前的Serializer類現在用ModelSerializer來實現

class StudentModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields =  ['id', 'name', 'age', 'sex']

預設情況下,所有的模型的欄位都將對映到序列化器上相應的欄位。
如果你希望在模型序列化器中使用預設欄位的一部分,你可以使用fieldsexclude選項來執行此操作

  • fields:需要哪些模型欄位
  • exclude:排除哪些模型欄位

官方強烈建議你使用fields屬性顯式的設定要序列化的欄位。這樣就不太可能因為你修改了模型而無意中暴露了資料。
如果我們需要使用模型的全部欄位,則可以將fields屬性設定成'__all__'

預設情況下,fields裡的欄位既參加序列化也參加反序列化,如果我們想某個欄位只序列化或反序列化可以定義extra_kwargs欄位,程式碼如下:

class StudentModelSerializer(serializers.ModelSerializer):
    # classes = ClassesModelSerializer(read_only=True)
    class Meta:
        model = Student
        fields =  ['id', 'name', 'age', 'sex', 'password']
        extra_kwargs = {
            "password": {
                "write_only": True
            },
           "id": {
               "read_only": False
           }
        }

上面程式碼如果不寫extra_kwargs,那麼password預設參加序列化和反序列化,那麼密碼就會返回給前端了,這裡我們定義了extra_kwargs欄位,在欄位中設定了password只能反序列化,那麼使用者只能提交密碼,而後臺不會返回密碼給前臺
當然,extra_kwargs也可以自定義錯誤資訊,如果業務有需要,可以檢視官方文件
 

指定巢狀序列化

上面我們都是單模型的序列化,但是實際業務中我們不會這麼簡單,一定會遇到關係模型的序列化,下面我們來講解關係模型的序列化
首先我們看一下models模型內容:

class Classes(models.Model):
    name = models.CharField(max_length=20, verbose_name="班級名")

    class Meta:
        db_table = "classes"


class Student(models.Model):

    SEX_CHOICES = (
        (1,'男'),
        (2, '女')
    )

    name = models.CharField(max_length=20, verbose_name='姓名')
    age = models.IntegerField(null=True, blank=True, verbose_name='年齡')
    sex = models.IntegerField(choices=SEX_CHOICES, default=1, verbose_name='性別')
    classes = models.ForeignKey(Classes, on_delete=models.SET_NULL, verbose_name="班級", null=True, related_name='students')
    class Meta:
        db_table = "student"

我們定義了Student學生類,裡面定義了一個外來鍵classes關聯Classes,一個班級中可以有多個學生,而一個學生只能屬於一個班級,典型的一對多的關係,接下來我們看序列化函式

class ClassesModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Classes
        fields = ['id', 'name', 'students']


class StudentModelSerializer(serializers.ModelSerializer):
    classes = ClassesModelSerializer(read_only=True)
    class Meta:
        model = Student
        fields =  ['id', 'name', 'age', 'sex', 'classes']

我們在StudentModelSerializer中增加了一個額外的欄位classes,並將欄位設定為只讀,一般外來鍵只做序列化,並且在fields列表中新增了該欄位。
注意:我們在建立外來鍵模型時,必須在外來鍵中設定related_name,如果沒設定,序列化時不會返回關聯的外來鍵內容

接下來我們訪問http://127.0.0.1:8000/drf/student/,會看到返回的學生表中包含了班級表的內容,如下

{
    "id": 1,
    "name": "jkc",
    "age": 18,
    "sex": 1,
    "classes": {
        "id": 1,
        "name": "班級1",
        "students": [
            1,
            15,
            18
        ]
    }
},

相關文章