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:
-
PrimaryKeyRelatedField
-
StringRelatedField
-
HyperlinkedRelatedField
-
HyperlinkedRelatedField
-
Use the serializer for the associated object
-
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