Serialization and deserialization of the Django framework

DRF in using the Django framework, it provides a very important feature is the serializer, such as we need to put front end receives the processing after the json data into the model, or forward set return data when need to translate into json data model objects, so the process model can be converted to json here called serialization, Converting JSON data into a model is called deserialization

Defining the serializer

To get the fields in the model, the fields in the serializer should have the same names as the fields in the model class

Custom field

Define methods

The Serializer inheritance in rest_framework. Serializers. Serializer module

Let’s say we define a serializer for the book class and a serializer for the hero class

Book class serializer

from rest_framework import serializers

class BookInfoSerializer(serializers.Serializer) :
    """ Book data serializer ""
    id = serializers.IntegerField(label='ID', read_only=True)
    btitle = serializers.CharField(label='name', max_length=20)
    bpub_date = serializers.DateField(label='Release Date', required=False)
    bread = serializers.IntegerField(label='Reading volume', required=False)
    bcomment = serializers.IntegerField(label='Comment volume', required=False)
image = serializers.ImageField(label='images', required=False) more than 1 v connection object field definition heroinfo_set = serializers. PrimarKeyRelatedField (label ='heroes', read_only=true,many=True) 
Copy the code

Hero serializer

class HeroInfoSerializers(serializers.Serializer) :
    GENDER_CHOICES = (
        (0.'male'),
        (1.'female'))id = serializers.IntegerField(label="ID", read_only=True)
    hname = serializers.CharField(label='name', max_length=20)
    hgender = serializers.ChoiceField(
        label='gender', choices=GENDER_CHOICES, required=False)
    hcomment = serializers.CharField(
        label='Description', max_length=200, required=False, allow_null=True)
     # multi-v1 associated object field definition
    # hbook = serializers. PrimaryKeyRelatedField (label = 'books', read_only = True)
    # hbook = serializers. HyperlinkedRelatedField (label = 'books', read_only = True, view_name =' books - the detail)
    hbook = BookRelateField(read_only=True)


Copy the code
  • Note:

The read_only argument in parentheses indicates that it is only used for serialization, required indicates whether it must be passed in, and the default is True

Field type and option parameters

field Field construction
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)
The regular field verifies the regular pattern [A-ZA-Z0-9-] +
URLField URLField(max_length=200, min_length=None, allow_blank=False)
UUIDField UUIDField(format=’hex_verbose’)
format:
1) ‘hex_verbose’ such as “five ffa ce0e9a5-5-654 – b – fb31a cee0-1238041”
2) “hex” such as “five ce0e9a55ffa654bcee01238041fb31a”
3) ‘int’ – such as: “123456789012312313134124512351145145114”
4) ‘URN’ e.g. “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: indicates the maximum number of digits
Decimal_palces: Position of the decimal point
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 is used the same way as 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:

The parameter name role
max_length The maximum length
min_lenght Minimum length
allow_blank Whether to allow null
trim_whitespace Whether to truncate whitespace characters
max_value The minimum value
min_value The maximum

General parameters:

The parameter name instructions
read_only Indicates that this field is used only for serialized output, default False
write_only Indicates that this field is only used to deserialize input. Default is False
required Indicates that this field must be entered when deserializing, and defaults to True
default Default value to use when deserializing
allow_null Indicates whether the field is allowed to pass None. The default is False
validators Validator used by this field
error_messages A dictionary containing error numbers and error messages
label The name of the field to display when HTML displays the API page
help_text Field help information displayed when HTML displays the API page

Quick definition using model classes

1. Definition method:

Serializer inheritance in rest_framework. Serializers. ModelSerializer module;

Specify the serialization type and option parameters of each field, which itself provides a verification behavior for the follow-up.

2. Functions provided:

  • Automatically generate a series of fields based on the module

  • Automatically generates Validators for Serializer based on the model class

  • Contains default create() and update()

Again, here are examples of books and heroes

Book Category Definition:

class BookInfoSerializer(serializers.ModelSerializer) :
    
# display the specified field
heroinfo_set =  serializers.PrimaryKeyRelatedField(label='heroes',read_only=True,many=True)

""" Book data serializer ""
    class Meta:
        model = BookInfo
        fields = '__all__'   # shows all fields
        fields = ('id'.'btitle'.'bpub_date') # indicates that only the corresponding field is displayed
        exclude = ('image'.)All fields except image, tuple type
        depth = 1 # nested hierarchy
read_only_fields = ('id'.'bread'.'bcomment') Use only for serialized output

Copy the code

Hero Class Definition

class HeroInfoModelSerializers(serializers.ModelSerializer) :
    class Meta:
        model = HeroInfo
        fields = ('id'.'hname'.'hgender'.'hbook')
        depth = 1
extra_kwargs = {
            'bread': {'min_value': 0.'required': True}},
            'bcomment': {'max_value': 0.'required': True}}},Copy the code
  • Note:

    • Model specifies which model class to refer to

    • Fields specifies which fields are generated for the model class

    • Exclude Specifies which fields are excluded

    • Depth indicates the number of nested levels

    • You can specify the display of the specified field above the Meta

    • Extra_kwargs adds or modifies existing fields with high priority

2. Serialization

(1) Create a Serializer object

Serializer Object construction mode

Serializer name (instance=None,data=empty,**kwary)

  • Note:

    • Instance represents a model class object

    • Data is used to deserialize incoming data

    • ** Wkargs can be passed named parameters, including context, which can be obtained from the context property of the Serializer object

(2) Basic query

from booktest.models import BookInfo
from booktest.serializers import BookInfoSerializer

Get single data
book = BookInfo.objects.get(id=2)
serializer = BookInfoSerializer(book)  The serializer is initialized

serializer.data Get data from the data method

# Retrieving multiple data needs to be marked with many parameters
book_qs = BookInfo.objects.all()
serializer = BookInfoSerializer(book_qs, many=True)
serializer.data

Copy the code

Associated Object Query

1. One-to-many associated query

1:n Book: Heroes

Associative model class name Lowercase _set is the field name, and multiple data needs to be annotated with the “many” parameter

class BookInfoSerializer(serializers.Serializer) :
    """ Book data serializer ""
    id = serializers.IntegerField(label='ID', read_only=True)
    btitle = serializers.CharField(label='name', max_length=20)
    bpub_date = serializers.DateField(label='Release Date', required=False)
    bread = serializers.IntegerField(label='Reading volume', required=False)
    bcomment = serializers.IntegerField(label='Comment volume', required=False)
image = serializers.ImageField(label='images', required=False)

    heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)  # new


Copy the code

2. Many-to-one associated query

N :1 Hero: books

class HeroInfoSerializer(serializers.Serializer) :
    """ Hero data serializer """
    GENDER_CHOICES = (
        (0.'male'),
        (1.'female'))id = serializers.IntegerField(label='ID', read_only=True)
    hname = serializers.CharField(label='name', max_length=20)
    hgender = serializers.ChoiceField(choices=GENDER_CHOICES, label='gender', required=False)
hcomment = serializers.CharField(label='Description', max_length=200, required=False, allow_null=True)

hbook = serializers.PrimaryKeyRelatedField(label='book', read_only=True)

Copy the code

3. Method used to associate fields:

  1. PrimaryKeyRelatedField

  2. StringRelatedField

  3. HyperlinkedRelatedField

  4. HyperlinkedRelatedField

  5. Use the serializer for the associated object

  6. Rewrite the to_representation method

Case study:

hbook = serializers.PrimaryKeyRelatedField(label='book', read_only=True) or hbook = serializers. PrimaryKeyRelatedField (label ='book', queryset=BookInfo.objects.all())
hbook = serializers.StringRelatedField(label='book')
hbook = serializers.HyperlinkedRelatedField(label='book', read_only=True, view_name='books-detail')
hbook = serializers.SlugRelatedField(label='book', read_only=True, slug_field='bpub_date')
hbook = BookInfoSerializer()

class BookRelateField(serializers.RelatedField) :
    Custom fields for processing books
    def to_representation(self, value) :
        return 'Book: %d %s' % (value.id, value.btitle)

Copy the code

Deserialization

Deserialization is divided into two steps:

  • Data validation

  • Save the data

Validation data

Before deserialization with serializer, validation is required. After validation, data can be obtained and saved as model class objects.

Before retrieving the serialized data, it is validated with the is_Valid method, which returns a Boolean value True or False;

Returns False on validation failure. In this case, you can return the error cause using the errors method.

Returns True after successful validation, in which case data can be obtained using the validATED_data method.

Check method 1:

Validates as defined serializers are specified types, such as DateField type must be time type

class BookInfo(models.Model) :
    btitle = models.CharField(max_length=20, verbose_name='name')
bpub_date = models.DateField(verbose_name='Release Date', null=True)...#---------- That's the serializer for -----------

from booktest.serializers import BookInfoSerializer
data = {'bpub_date': 123}
Create a serializer object
The second parameter, data, is used for deserialization, passing in the dictionary type
Is_valid is required, and raise_exception is set to True to throw an exception to the front end
The error attribute is errors, and the validATED_data attribute is validated_data
serializer = BookInfoSerializer(data=data)
serializer.is_valid(raise_exception=True)  # return False,
serializer.errors
# {'btitle': [ErrorDetail(string='This field is required.', code='required')], 'bpub_date': [ErrorDetail(string='Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]].', code='invalid')]}
serializer.validated_data  # {}

Copy the code

Verification method two:

Field options

Such as:

Option parameters:

The parameter name role
max_length = 10 The maximum length is 10
min_lenght =1 The minimum length is not less than 1
allow_blank Whether to allow null
trim_whitespace Whether to truncate whitespace characters
max_value The minimum value
min_value The maximum

Test Method three:

Validate individual fields

Def validate_ field name (self,value)

Note: The value argument represents the value of the field passed in

class BookInfoSerializer(serializers.Serializer) :
""" Book data serializer ""
btitle = models.CharField(max_length=20, verbose_name='name')
    bpub_date = models.DateField(verbose_name='Release Date', null=True)...def validate_btitle(self, value) :
        if 'django' not in value.lower():
            raise serializers.ValidationError("The book is not about Django.")
        return value

Copy the code

test

from booktest.serializers import BookInfoSerializer
data = {'btitle': 'python'}
serializer = BookInfoSerializer(data=data)
serializer.is_valid()  # False   
serializer.errors
# {'btitle': [ErrorDetail(string=' the book is not about Django ', code='invalid')]}

Copy the code

Verification method four:

Validates multiple fields

Def validate(self,attrs)

Note: The attrs parameter is actually the data dictionary

class BookInfoSerializer(serializers.Serializer) :
    """ Book data serializer "".def validate(self, attrs) :
        bread = attrs['bread']
        bcomment = attrs['bcomment']
        if bread < bcomment:
            raise serializers.ValidationError('Read less than reviewed')
        return attrs

Copy the code

Testing:

from booktest.serializers import BookInfoSerializer
data = {'btitle': 'about django'.'bread': 10.'bcomment': 20}
s = BookInfoSerializer(data=data)
s.is_valid()  # False
s.errors
# {'non_field_errors': [ErrorDetail(string=' read less than comment ', code='invalid')]}

Copy the code

Check Method 5

Customize the verification method

def about_django(value) :
    if 'django' not in value.lower():
        raise serializers.ValidationError("The book is not about Django.")

class BookInfoSerializer(serializers.Serializer) :
    """ Book data serializer ""
    id = serializers.IntegerField(label='ID', read_only=True)
btitle = serializers.CharField(label='name', max_length=20, validators = [about_django])...Copy the code

test

from booktest.serializers import BookInfoSerializer
data = {'btitle': 'python'}
serializer = BookInfoSerializer(data=data)
serializer.is_valid()  # False   
serializer.errors
# {'btitle': [ErrorDetail(string=' the book is not about Django ', code='invalid')]}

Copy the code

(2) Data preservation

When calling the save method in Serializer, we need to manually create the create() and update() methods

When creating a serialized object, you can use partial=True to allow partial field updates

Create new data

The create method in the serializer is automatically called to create new data when only data data is passed in to create a serialized object

Define the create method in the serializer

Note: The ** validATED_data argument is actually the data dictionary data passed in

class BookInfoSerializer(serializers.Serializer) :
    """ Book data serializer "".def create(self, validated_data) :
        "" "new "" "
        return BookInfo.objects.create(**validated_data)

Copy the code

test

from db.serializers import BookInfoSerializer
data = {'btitle': 'Canonization'}
serializer = BookInfoSerializer(data=data)
serializer.is_valid()  # True
serializer.save()  # 
      

Copy the code

Update the data

Data is updated when instance objects and data data are passed in when serialized objects are created

The system automatically calls the update method,

Note: Instance is the instance object to be updated, and VALIDATED_data is the updated data

class BookInfoSerializer(serializers.Serializer) :
    """ Book data serializer "".def create(self, validated_data) :
        "" "new "" "
        return BookInfo.objects.create(**validated_data)

    def update(self, instance, validated_data) :
        """ Update, instance is the object instance to be updated """
        instance.btitle = validated_data.get('btitle', instance.btitle)
        instance.bpub_date = validated_data.get('bpub_date', instance.bpub_date)
        instance.bread = validated_data.get('bread', instance.bread)
        instance.bcomment = validated_data.get('bcomment', instance.bcomment)
        instance.save() Note that data needs to be saved
        return instance

Copy the code