Serializer serializer

Posted by ntroycondo on Tue, 01 Feb 2022 06:04:45 +0100

Serializer serializer

effect:

  1. Serialization, the serializer will convert the model object into a dictionary, and then into a json string after response
  2. 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 namemeaning
instanceWhen used for serialization, the model class object is passed in
dataWhen used for deserialization, the data to be deserialized is passed in
contextAdd 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.
manyWhen the instance parameter is a model list, the value of many must be True
  1. The serializer needs to be called manually in the view
  2. When using the serializer, you need to pass the data
  3. The serializer's field declaration class forms the system.

3. Use of serializer

The use of serializers is divided into two stages:

  1. When requested by the client, the serializer can be used to deserialize the data.
  2. 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")
12
Inverse sequence verification method Ivalidate_ Field name, for < field_ Name > field
Inverse sequence verification method Ivalidate. When comparing and validating multiple fields at the same time
Inverse sequence verification method IIIValidators 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 namemeaning
modelIndicates the model class that needs to be declared and called
fieldsIndicates which fields of the model class are generated for__ all__ The table name contains all fields, and you can also specify which fields
excludeClearly exclude which fields
read_only_fieldsIndicates a read-only field, i.e. only for serialized output
extra_kwargAdd or modify the original option parameters for ModelSerializer

3.4 serializer reference

1. Common field types:

fieldField construction method
BooleanFieldBooleanField()
NullBooleanFieldNullBooleanField()
CharFieldCharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
EmailFieldEmailField(max_length=None, min_length=None, allow_blank=False)
RegexFieldRegexField(regex, max_length=None, min_length=None, allow_blank=False)
SlugFieldSlugField(maxlength=50, min_length=None, allow_blank=False) regular field, verify the regular pattern [a-zA-Z0-9 -]+
URLFieldURLField(max_length=200, min_length=None, allow_blank=False)
UUIDFieldUUIDField(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"
IPAddressFieldIPAddressField(protocol='both', unpack_ipv4=False, **options)
IntegerFieldIntegerField(max_value=None, min_value=None)
FloatFieldFloatField(max_value=None, min_value=None)
DecimalFieldDecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: maximum digits decimal_palces: decimal point position
DateTimeFieldDateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
DateFieldDateField(format=api_settings.DATE_FORMAT, input_formats=None)
TimeFieldTimeField(format=api_settings.TIME_FORMAT, input_formats=None)
DurationFieldDurationField()
ChoiceFieldChoiceField(choices) choices are used in the same way as Django
MultipleChoiceFieldMultipleChoiceField(choices)
FileFieldFileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ImageFieldImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ListFieldListField(child=, min_length=None, max_length=None)
DictFieldDictField(child=)

2. Option parameters

Parameter nameeffect
max_lengthMaximum length
min_lenghtMinimum length
allow_blankAllow to be empty
trim_whitespaceTruncate white space characters
max_valueminimum value
min_valueMaximum

3. General parameters

Parameter nameexplain
read_onlyIndicates that this field is only used for serialized output. The default is False
write_onlyIndicates that this field is only used for deserialization input. The default is False
requiredIndicates that this field must be entered during deserialization. The default is True
defaultDefault value to use when deserializing
allow_nullIndicates whether the field is allowed to pass in None. The default is False
validatorsValidator used for this field
error_messagesA dictionary containing error numbers and error messages
labelThe name of the field to be displayed when displaying API pages in HTML
help_textUsed to display field help prompt information when HTML displays API pages

Topics: DRF