Serializer serializer
effect:
- Serialization, the serializer will convert the model object into a dictionary, and then into a json string after response
- Deserialization is to turn the data sent by the client into a dictionary after request. The serializer completes the data verification function, and then turns the dictionary into a model
1. Define serializer
models.py
from django.db import models # Create your models here. class Student(models.Model): # Model field name = models.CharField(max_length=100,verbose_name="full name",help_text="Prompt text:Account number cannot be empty!") sex = models.BooleanField(default=True,verbose_name="Gender") age = models.IntegerField(verbose_name="Age") class_null = models.CharField(max_length=5,verbose_name="Class number") description = models.TextField(verbose_name="Personal signature") class Meta: db_table="tb_student" verbose_name = "student" verbose_name_plural = verbose_name
serializers.py
from rest_framework import serializers #Declare serializers. All serializers should inherit from Serializer directly or indirectly class StudentSerializer(serializers.Serializer): """Student information serializer""" # 1. Fields requiring data conversion id = serializers.IntegerField() name = serializers.CharField() age = serializers.IntegerField() sex = serializers.BooleanField() description = serializers.CharField() # 2. Write code to add and update models def create(self, validated_data): pass def update(self, instance, validated_data): pass # 3. Validation code (used in deserialization)
be careful:
1.serializer can be defined not only for database model classes, but also for data of non database model classes
2. Create Serializer object
The construction method of Serializer is:
Serializer(instance=None, data=empty, **kwarg)
explain:
Parameter name | meaning |
---|---|
instance | When used for serialization, the model class object is passed in |
data | When used for deserialization, the data to be deserialized is passed in |
context | Add additional data serializer = AccountSerializer(account, context={'request': request}). The data attached through the context parameter can be obtained through the context attribute of the Serializer object. |
many | When the instance parameter is a model list, the value of many must be True |
- The serializer needs to be called manually in the view
- When using the serializer, you need to pass the data
- The serializer's field declaration class forms the system.
3. Use of serializer
The use of serializers is divided into two stages:
- When requested by the client, the serializer can be used to deserialize the data.
- When the server responds, the serializer can be used to serialize the data.
3.1 serialization
1) Find out a student object first
from students.models import Student student = Student.objects.get(id=3)
2) Construct serializer object
from .serializers import StudentSerializer serializer = StudentSerializer(instance=student)
3) Get serialized data
The serialized data can be obtained through the data attribute
serializer.data # {'id': 4, 'name': 'Xiao Zhang', 'age': 18, 'sex': True, 'description': 'monkey Sai Lei'}
4) Full view code:
urls.py
from . import views urlpatterns = [ re_path("student/(?P<pk>[0-9]{4})", views.StudentView.as_view()) ]
views.py
from django.views import View from students.models import Student from .serializers import StudentSerializer from django.http.response import JsonResponse class StudentView(View): """Serialize and transform single model data using serializer""" def get(self,request,pk): # get data student = Student.objects.get(pk=pk) # Data conversion [serialization process] serializer = StudentSerializer(instance=student) print(serializer.data) # Response data return JsonResponse(serializer.data)
5) If the query set to be serialized is a QuerySet containing multiple pieces of data, you can add the many=True parameter to supplement the description
urls.py
from . import views urlpatterns = [ path("student/", views.StudentView.as_view()) ]
view.py
"""Serialize and transform multiple model data using serializer""" def get(self,request): # get data student_list = Student.objects.all() # Convert data [serialization process] # If you convert multiple model object data, you need to add many=True serializer = StudentSerializer(instance=student_list,many=True) print( serializer.data ) # Serializer converted data # Response data to client # If the declared data is json = false, the returned data is json = false return JsonResponse(serializer.data,safe=False) # Access results: # [OrderedDict([('id', 1), ('name', 'xiaoming'), ('age', 20), ('sex', True), ('description ',' test ')]), ordereddict ([('id', 2), ('name ',' Xiaohui '), ('age', 22), ('sex ', true), ('description', 'later test')), OrderedDict([('id', 4), ('name', 'Xiaozhang'), ('age', 18), ('sex', True), ('description ',' monkey race ')]]
3.2 deserialization
3.2.1 data verification
When using serializer for deserialization, the data needs to be verified before obtaining the successfully verified data or saving it as a model class object.
mysite/urls.py
path("drf/", include("students.urls")),
students/urls
from django.urls import path from . import views urlpatterns = [ path("student/", views.StudentView.as_view()) ]
students/serializers.py
#Reverse sequence verification method 3: def check_sex_value(data): # Field validation function if data not in [1, 0]: raise serializers.ValidationError("sex value only have 1 and 0") class StudentSerializer(serializers.Serializer): id = serializers.IntegerField(label="ID", read_only=True) name = serializers.CharField(label="name", max_length=20, required=True) #Inverse sequence verification method III sex = serializers.IntegerField(label="Gender", required=False, allow_null=True, validators=[check_sex_value]) age = serializers.IntegerField(label="Age", required=True) class_num = serializers.CharField(label="Class number", required=False) description = serializers.CharField(required=False, allow_null=True, allow_blank=True) #Reverse sequence verification method I: def validate_name(self, attr): print(f"attr:{attr}") if attr == "eagle": raise serializers.ValidationError("Sorry, you're too fierce") return attr #Reverse sequence verification method 2: def validate(self, attrs): print(attrs) if attrs.get("age") > 60 and attrs.get("sex") == 1: raise serializers.ValidationError("Sorry, men can't be older than 60") return attrs
students/views.py
class StudentView(View): def get(self, request): student = Student.objects.all() #The serializer object is constructed and the data to be deserialized is passed to the data construction parameter for verification serializer = StudentSerializer(instance=student, many=True) print(serializer.data) return JsonResponse(serializer.data, safe=False) def post(self, request): print(request.body) data = json.loads(request.body) serializer = StudentSerializer(data=data) #raise_exception=True throw exception serializers when validation fails ValidationError #HTTP 400 Bad Request response will be returned to the front end result=serializer.is_valid(raise_exception=True) print(f"success:{result}") print(f"Success data:{serializer.validated_data()}") print(f"fail:{serializer.errors}") return HttpResponse("ok")
1 | 2 |
---|---|
Inverse sequence verification method I | validate_ Field name, for < field_ Name > field |
Inverse sequence verification method I | validate. When comparing and validating multiple fields at the same time |
Inverse sequence verification method III | Validators add the validators option parameter in the field to supplement the validation behavior |
3.2.2 data saving and updating
After the previous data validation is successful, we can use the serializer to complete the data deserialization process This process can convert data into model class objects
This can be achieved by implementing the create() and update() methods.
students/serializer.py
class StudentSerializer(serializers.Serializer): id = serializers.IntegerField(label="ID", read_only=True) name = serializers.CharField(label="name", max_length=20, required=True) sex = serializers.IntegerField(label="Gender", required=False, allow_null=True, validators=[check_sex_value]) age = serializers.IntegerField(label="Age", required=True) class_num = serializers.CharField(label="Class number", required=False) description = serializers.CharField(required=False, allow_null=True, allow_blank=True) @staticmethod def validate_name(attr): if attr == "eagle": raise serializers.ValidationError("Sorry, you're too fierce") return attr def validate(self, attrs): if attrs.get("age") > 60 and attrs.get("sex") == 1: raise serializers.ValidationError("Sorry, men can't be older than 60") return attrs def create(self, validated_data): return Student.objects.create(**validated_data) def update(self, instance, validated_data): instance.name = validated_data.get("name", instance.name) instance.sex = validated_data.get("sex", instance.sex) instance.age = validated_data.get("age", instance.age) instance.class_num = validated_data.get("class_num", instance.class_num) instance.description = validated_data.get("description", instance.description) instance.save() return instance
students/views.py
class StudentView(View): def get(self, request): student = Student.objects.all() serializer = StudentSerializer(instance=student, many=True) print(serializer.data) return JsonResponse(serializer.data, safe=False) def post(self, request): print(request.body) data = json.loads(request.body) serializer = StudentSerializer(data=data) print(f"success:{serializer.is_valid(raise_exception=True)}") print(f"fail:{serializer.errors}") serializer.save() return HttpResponse("New data generated successfully") def put(self, request): print(request.body) data = json.loads(request.body) put_id = data.get("id") student = Student.objects.get(pk=put_id) # Use the partial parameter to allow some fields to be updated. Even if there is a required field and it is not submitted, no exception will be thrown serializer = StudentSerializer(instance=student, data=data, partial=True) serializer.is_valid(raise_exception=True) # The keyword parameters passed in save can also be obtained in the create and update methods data=serializer.save()#The save() method can return a data object instance return HttpResponse("Update complete")
After implementing the above two methods, when deserializing data, you can return a data object instance through the save() method
If the instance instance is not passed when the serializer object is created, create() is called when the save() method is called. On the contrary, if the instance is passed, update() is called when the save() method is called.
3.3 model class serializer
If you want to provide a Serializer for Django's model class, you can use the ModelSerializer model class to quickly create a Serializer class
ModelSerializer is the same as a regular Serializer, but provides
- Automatically generate a series of fields based on model classes
- Automatically generate validators for Serializer based on model classes, such as unique_together
- Contains the default implementation of create() and update()
class StudentModel2Serializer(serializers.ModelSerializer): class Meta: model = Student fields = ("id", "name", "sex", "age", "class_num") exclude = ("description",) read_only_fields = ('id',) extra_kwargs = { "id": { "required": True}, "name": {"required": True}, "age": {"max_value": 60, "required": True} }
class Student2ViewSet(View): def get(self): student = Student.objects.all() serializer = StudentModel2Serializer(instance=student, many=True) print(serializer.data) return JsonResponse(serializer.data, safe=False) def post(self, request): print(request.body) data = json.loads(request.body) serializer = StudentModel2Serializer(data=data) serializer.is_valid(raise_exception=True) serializer.save() return HttpResponse(serializer.data)
Field description
Field name | meaning |
---|---|
model | Indicates the model class that needs to be declared and called |
fields | Indicates which fields of the model class are generated for__ all__ The table name contains all fields, and you can also specify which fields |
exclude | Clearly exclude which fields |
read_only_fields | Indicates a read-only field, i.e. only for serialized output |
extra_kwarg | Add or modify the original option parameters for ModelSerializer |
3.4 serializer reference
1. Common field types:
field | Field construction method |
---|---|
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) regular field, verify 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 'e.g. "5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2)' Hex 'e.g. "5ce0e9a55ffa654bcee01238041fb31a" 3)' int '- e.g. "12345678901231313134124512351145114" 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: maximum digits decimal_palces: decimal point position |
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 are used in 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=) |
2. Option parameters
Parameter name | effect |
---|---|
max_length | Maximum length |
min_lenght | Minimum length |
allow_blank | Allow to be empty |
trim_whitespace | Truncate white space characters |
max_value | minimum value |
min_value | Maximum |
3. General parameters
Parameter name | explain |
---|---|
read_only | Indicates that this field is only used for serialized output. The default is False |
write_only | Indicates that this field is only used for deserialization input. The default is False |
required | Indicates that this field must be entered during deserialization. The default is True |
default | Default value to use when deserializing |
allow_null | Indicates whether the field is allowed to pass in None. The default is False |
validators | Validator used for this field |
error_messages | A dictionary containing error numbers and error messages |
label | The name of the field to be displayed when displaying API pages in HTML |
help_text | Used to display field help prompt information when HTML displays API pages |