Explanation of Django Serialization Component Serializers Usage

  • 2021-12-04 10:33:19
  • OfStack

Directory 01, Why Serialize Components 02. Basic use of serialization components 03. Serialize Component Common Fields 04. Serialization components is_valid, validated_data 05. Serialize component verification field 06. Serialization Component.create () and. update () 07. Serialization component ModelSerializer 08. Serialize components to construct complex structures 09. The serialization component modifies the return values to_representation, to_internal_value

This paper mainly systematically explains the use of django rest framwork serialization component, which can solve 90% of the serialization problem in the work after reading it basically. The writing refers to the official document https://www.django-rest-framework.org/api-guide/serializers/# modelserializer, which is divided into the following 9 parts:

01, Why Serialize Components

We know that json data structure is commonly used in front and back end interaction, At the back end, we often want to return an object to the front end. However, json serialization does not serialize objects (although you can add serialization parameters. encoder serialization principles and serialization components almost need to define their own serialization classes and returned structures), So we have our serialization component, you can customize the specific structure to serialize the object back to the front end, and at the same time, you can check the data of the parameters passed in from the front end.

02. Basic use of serialization components

models


from django.db import models

# Create your models here.


class Book(models.Model):
    id = models.IntegerField(primary_key=True)
    title = models.CharField(max_length=255)
    desc = models.CharField(max_length=255)
    is_deleted = models.IntegerField(choices=[(1, " Delete "), (0, " Not deleted ")])
    author = models.CharField(max_length=255)

serializer


from rest_framework.serializers import Serializer
from rest_framework import serializers


class BookSerializer(Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField()
    desc = serializers.CharField()
    is_deleted = serializers.ChoiceField(choices=[(1, " Delete "), (0, " Not deleted ")], source="get_is_deleted_display")
    author = serializers.CharField()

views


from app01.models import Book
from app01.serializer import BookSerializer
from django.http import HttpResponse, JsonResponse

# Create your views here.


def get_books(request):
    books = Book.objects.all()
    se = BookSerializer(books, many=True)
    return JsonResponse(se.data, safe=False)

The result returns:

[{"id": 1, "title": "Living", "desc": "Telling the life of a generation", "is_deleted": "Not deleted", "author": "Yu Hua"}]

model and serializer are very similar in writing, but the internal logic model is the relationship mapping with database tables, and serializer is the serialization and deserialization of objects.

03. Serialize Component Common Fields

Common field types

字段 字段构造方式
BooleanField BooleanField()
NullBooleanField NullBooleanField()
CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
EmailField EmailField(max_length=None, min_length=None, allow_blank=False)
RegexField RegexField(regex, max_length=None, min_length=None, allow_blank=False)
SlugField SlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+
URLField URLField(max_length=200, min_length=None, allow_blank=False)
UUIDField UUIDField(format='hex_verbose')
format:
1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a"
3)'int' - 如: "123456789012312313134124512351145145114"
4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
IPAddressField IPAddressField(protocol='both', unpack_ipv4=False, **options)
IntegerField IntegerField(max_value=None, min_value=None)
FloatField FloatField(max_value=None, min_value=None)
DecimalField DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)
max_digits: 最多位数
decimal_palces: 小数点位置
DateTimeField DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
DateField DateField(format=api_settings.DATE_FORMAT, input_formats=None)
TimeField TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
DurationField DurationField()
ChoiceField ChoiceField(choices)
choices与Django的用法相同
MultipleChoiceField MultipleChoiceField(choices)
FileField FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ImageField ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ListField ListField(child=, min_length=None, max_length=None)
DictField DictField(child=)

Option parameters:

名称 作用
max_length 最大长度
min_lenght 最小长度
allow_blank 是否允许为空
trim_whitespace 是否截断空白字符
max_value 最大值
min_value 最小值

General parameter

参数名称 说明
read_only 表明该字段仅用于序列化输出,默认False
write_only 表明该字段仅用于反序列化输入,默认False
required 表明该字段在反序列化时必须输入,默认True
default 反序列化时使用的默认值
allow_null 表明该字段是否允许传入None,默认False
validators 该字段使用的验证器
error_messages 包含错误编号与错误信息的字典
label 用于HTML展示API页面时,显示的字段名称
help_text 用于HTML展示API页面时,显示的字段帮助提示信息

Here, we will talk about an additional parameter source, which is explained in the official document as follows:

The name of the property that will be used to populate the field. It can be a method that only accepts self parameters, such as URLField (source= 'get_absolute_url'), or it can use dot-point symbols to traverse attributes, such as EmailField (source= 'user. email'). default may need to supply a value if any object does not exist or is empty during property traversal when using dot-point symbols to serialize fields.

The value source= '*' has a special meaning to indicate that the entire object should be passed to the field. This is useful for creating nested representations or for fields that require access to the complete object to determine the output representation.

The default is the field name.

Among them, the more commonly used usage:

1. source= "get_field_name_display" As shown above, the explanation corresponding to the option can be displayed in the choice field, which means that the official explanation can be a method that only accepts self parameters, that is, the method that can be called by serializer objects can be filled in source (self needs to be passed in the method), and the internal logic is that this field will display the return result of this method.

2. source= 'user. email' This usage is often used in the subclass of ModelSerializer, where user is an User object, which refers to displaying email attributes of user, which is often used when we want to display the attributes of foreign key object user at the same level as that of this object, instead of the next level.

04. Serialization Components is_valid, validated_data

When we define the serializer, how do we verify the incoming fields? That is the is_valid method, which determines whether an incoming field is legitimate based on the validation rules that define the serializer.


serializer = CommentSerializer(data={'email': 'foobar', 'content': 'baz'})
serializer.is_valid()
# False
serializer.errors
# {'email': ['Enter a valid e-mail address.'], 'created': ['This field is required.']}

Then serializer.validated_data can get the verified data dictionary.

05. Serialize component verification field

There are three common ways to serialize component validation fields:

1. First, in the validators attribute of the field, a checkout method list is passed in, such as validators= (my_validator,) where the checkout rule is defined in my_validator.


def multiple_of_ten(value):
    if value % 10 != 0:
        raise serializers.ValidationError('Not a multiple of ten')

class GameRecord(serializers.Serializer):
    score = IntegerField(validators=[multiple_of_ten])

2. The most commonly used function is to define an validate_field_name (self, value) (where field_name refers to the field name), and the specific logic is inside the function.


from rest_framework import serializers

class BlogPostSerializer(serializers.Serializer):
    title = serializers.CharField(max_length=100)
    content = serializers.CharField()

    def validate_title(self, value):
        """
        Check that the blog post is about Django.
        """
        if 'django' not in value.lower():
            raise serializers.ValidationError("Blog post is not about Django")
        return value

3. The last one is to define an validate (self, data) where data is the key-value pair of all fields, so this verification method is object-level verification.


from rest_framework import serializers

class EventSerializer(serializers.Serializer):
    description = serializers.CharField(max_length=100)
    start = serializers.DateTimeField()
    finish = serializers.DateTimeField()

    def validate(self, data):
        """
        Check that start is before finish.
        """
        if data['start'] > data['finish']:
            raise serializers.ValidationError("finish must occur after start")
        return data

Of course, maybe when you see this, you will ask why? how? Can only say that the source code is the best answer.

06. Serialization Component.create () and. update ()

In the serialization class we define, we can add create and update methods. When we need to create records or update a certain piece of data in the database table according to the deserialized data, we can define the corresponding logic in create methods and update methods.


class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()
     def create(self, validated_data):
        return Comment.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        instance.save()
        return instance

Next, call serializer. save () command to create a record or update a record, which determines when to create and when to update save. The key lies in the instantiation of serializer.


# .save() will create a new instance.
serializer = CommentSerializer(data=data)
serializer.save()
# .save() will update the existing `comment` instance.
 serializer = CommentSerializer(comment, data=data)

serializer.save()

When org class instantiation does not pass in model object, create method will be called to create a record, and if model object is passed in Serializer class instantiation, update method will be called to update a record.

Sometimes we need other fields besides deserialized fields. What should we do? We can pass in the parameter name and value in save, and we can get the corresponding value according to the parameter name in validated_data.


serializer.save(owner=request.user)

So we can get the user object at validated_data. get ("owner").

07. Serialization component ModelSerializer

ModelSerializer is very similar to the ModelForm component of the form, which greatly simplifies our development. The corresponding model can be defined in the internal class Meta, and ModelSerializer will automatically generate Field corresponding to model field without our definition.


from rest_framework.serializers import Serializer
from rest_framework import serializers


class BookSerializer(Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField()
    desc = serializers.CharField()
    is_deleted = serializers.ChoiceField(choices=[(1, " Delete "), (0, " Not deleted ")], source="get_is_deleted_display")
    author = serializers.CharField()
0

Among them, fields defines serialized fields, and if it is all fields, write __all__. In the above example, we did not define specific fields, and ModelSerializer helps us automatically generate Field of 'id', 'account_name', 'users' and 'created'.

08. Serialize components to construct complex structures

The following is a serializer with 1-to-many and many-to-many fields

serializer


from rest_framework.serializers import Serializer
from rest_framework import serializers


class BookSerializer(Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField()
    desc = serializers.CharField()
    is_deleted = serializers.ChoiceField(choices=[(1, " Delete "), (0, " Not deleted ")], source="get_is_deleted_display")
    author = serializers.CharField()
1

views


from rest_framework.serializers import Serializer
from rest_framework import serializers


class BookSerializer(Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField()
    desc = serializers.CharField()
    is_deleted = serializers.ChoiceField(choices=[(1, " Delete "), (0, " Not deleted ")], source="get_is_deleted_display")
    author = serializers.CharField()
2

If you use ModelSerializer:

serializer


from app01 import models
class PublishSerializer(serializers.ModelSerializer): 
    class Meta: # Fixed writing 
    #  Specifies that you want to serialize Book Table 
    model = models.Book
    # Specify the fields to serialize 
    fields = ['nid','name']
    # Serialize all fields 
    fileds ='__all__ '  
    # Fields to exclude (cannot be associated with fileds Used together) 
    # exclude = ['name','price'] 
    # Depth determination 
    depth = 1 
    # If you don't follow the parent class and want to define the displayed fields by yourself, , Self-defined 1 Override the field properties of the parent class. 
    publish = serializers.SerializerMethodField()  #1 Pair multiple fields 
    def get_publish(self,obj):
        return {'id ' :obj.publish.pk,'name':obj.publish.name}

Here, the parameter depth under 1 is explained additionally: when an object is foreign key to another object, another object is foreign key to another object, and so on. The function of depth is to determine the foreign key depth during serialization.

The main point of the complex serializer is the use of serializers. SerializerMethodField () and get_field_name to get the field value you want, and the use of source, as mentioned above.

09. Serialization component modifies return values to_representation, to_internal_value

to_representation (self, instance): If the serializer defines this method, you can change the value of the serialized object data, that is, the value of serializer. data, and you can reconstruct the return value according to your own business scenario.


from rest_framework.serializers import Serializer
from rest_framework import serializers


class BookSerializer(Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField()
    desc = serializers.CharField()
    is_deleted = serializers.ChoiceField(choices=[(1, " Delete "), (0, " Not deleted ")], source="get_is_deleted_display")
    author = serializers.CharField()
4

to_internal_value (self, data): data is an unchecked data field. This method can check and modify the deserialized value, and then return. If you don't want to modify the deserialized value just for validation, you can use the validate method instead.


from rest_framework.serializers import Serializer
from rest_framework import serializers


class BookSerializer(Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField()
    desc = serializers.CharField()
    is_deleted = serializers.ChoiceField(choices=[(1, " Delete "), (0, " Not deleted ")], source="get_is_deleted_display")
    author = serializers.CharField()
5

To sum up, one of the two methods is used to reconstruct validated_data and return, and the other is used to reconstruct the value of serializer. data and return.


Related articles: