DRF framework serialization

brief introduction

DRF (Django REST framework) is a powerful and flexible toolkit for building RESTful web APIs. It is a secondary development based on Django framework. It is called DRF framework or REST framework for short.

characteristic

  • It provides a powerful Serializer serializer, which can serialize and deserialize efficiently
  • It provides extremely rich class views, Mixin extension classes and ViewSet view sets
  • Provides an intuitive Web API interface
  • Multiple identity authentication and authority authentication
  • Powerful sorting, filtering, paging, search, flow limiting and other functions
  • Extensibility and rich plug-ins

install

pip install djangorestframework

Set rest_ Add framework to installed_ In apps settings:

INSTALLED_APPS = [
    'rest_framework',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Basic use of serializers

Serializer - serializer
The biggest feature of the drf framework is its serializer. Its functions are as follows:

  • Serialize the model object into a dictionary and provide it to the view in the future. After the response, it becomes a json string.
  • The data sent by the client is called request through the view to become a python dictionary, and the serializer can convert the dictionary into a model.
  • Complete the function of database checksum operation

Define serializer

Continue to use the student table you created earlier to demonstrate the basic use of the serializer

from django.db import models

class Student(models.Model):
    """
    Student list
    """
    name = models.CharField('Student name', max_length=200, unique=True, help_text='Student name')
    gender = models.SmallIntegerField('Gender', default='1', help_text='Gender')
    hobby = models.CharField('hobby', max_length=200, null=True, blank=True, help_text='hobby')
    age = models.IntegerField('Age', null=True, )
    create_time = models.DateTimeField('Creation time', auto_now_add=True, help_text='Creation time')
    grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True, related_name='students')  # Set foreign keys, cascade delete)

    class Meta:
        """
        Metadata,
        """
        db_table = 'student'  # Specifies that the current model created by the current model does not write the default current model name Student
        verbose_name = 'Student information sheet'  # notes
        verbose_name_plural = verbose_name  # Specify as plural

Create the serializers.py file in the application directory, define classes and inherit rest_framework.serializers.Serializer is similar to the model. This serializer is defined to serialize project objects, so the fields correspond to the fields in the model one by one.

from rest_framework import serializers


class ProjectSerializer(serializers.Serializer):
    """
    Project serializer
    """
    id = serializers.IntegerField(label='student id', read_only=True) # read-only
    name = serializers.CharField(label='Student name')
    hobby = serializers.CharField(label='hobby',allow_null=True,required=False) # allow_null allows receiving null,required=False. This field can be ignored when instantiating an object
    age = serializers.IntegerField(label='Age')
    c_time = serializers.DateTimeField(label='Creation time', read_only=True)

Use serializer

1, Serialize model instances

In [12]: from projects.models import *
In [13]: from projects.serializers import ProjectSerializer

In [14]: s=Student.objects.first() # Instantiate an object
In [15]: p = ProjectSerializers(s) # Convert to dictionary by serializer
In [16]: p.data
Out[17]: {'id': 3, 'name': 'test3', 'hobby': 'play a game', 'age': 19}

In order to complete the serialization process and convert it to json, you need to import

Out[17]: from rest_framework.renderers import JSONRenderer
In [18]: JSONRenderer().render(p.data)
Out[18]: b'{"id":3,"name":"test3","hobby":"\xe7\x8e\xa9\xe6\xb8\xb8\xe6\x88\x8f","age":19}'

2, Serialize query set
Specify that the many parameter is equal to True when using the serializer

In [22]: s1 = Student.objects.all()

In [23]: p1 = ProjectSerializers(s1)
 
In [25]: p1.data

In [26]: p1 = ProjectSerializers(s1,many=True)

In [27]: p1.data 

Out[27]: [OrderedDict([('id', 3), ('name', 'test3'), ('hobby', 'play a game'), ('age', 19)]), OrderedDict([('id', 4), ('name', 'Zhang San'), ('hobby', 'play'), ('age', 21)]), OrderedDict([('id', 5), ('name', 'zhaom'), ('hobby', 'play'), ('age',
112)]), OrderedDict([('id', 8), ('name', 'Ah San'), ('hobby', 'play'), ('age', 22)]), OrderedDict([('id', 9), ('name', 'test2'), ('hobby', 'wan'), ('age', 10)]), OrderedDict([('id', 13), ('name', 'ls'), ('hobby', None), ('age', 33)]),
OrderedDict([('id', 14), ('name', 'laa'), ('hobby', None), ('age', 35)]), OrderedDict([('id', 15), ('name', 'aa'), ('hobby', 'con'), ('age', 36)]), OrderedDict([('id', 16), ('name', 'ceaaa'), ('hobby', '11'), ('age', 1111)]), Ordered
Dict([('id', 17), ('name', '111'), ('hobby', ''), ('age', 222)]), OrderedDict([('id', 18), ('name', 'test33'), ('hobby', 'Play basketball'), ('age', 99)]), OrderedDict([('id', 21), ('name', 'test'), ('hobby', 'Play basketball'), ('age', 991)])]

In [28]: JSONRenderer().render(p1.data)

Out[28]: b'[{"id":3,"name":"test3","hobby":"\xe7\x8e\xa9\xe6\xb8\xb8\xe6\x88\x8f","age":19},{"id":4,"name":"\xe5\xbc\xa0\xe4\xb8\x89","hobby":"\xe7\x8e\xa9","age":21},{"id":5,"name":"zhaom","hobby":"play","age":112},{"id":8,"name":"\
xe9\x98\xbf\xe4\xb8\x89","hobby":"play","age":22},{"id":9,"name":"test2","hobby":"wan","age":10},{"id":13,"name":"ls","hobby":null,"age":33},{"id":14,"name":"laa","hobby":null,"age":35},{"id":15,"name":"aa","hobby":"con","age":36},{"
id":16,"name":"ceaaa","hobby":"11","age":1111},{"id":17,"name":"111","hobby":"","age":222},{"id":18,"name":"test33","hobby":"\xe6\x89\x93\xe7\xaf\xae\xe7\x90\x83","age":99},{"id":21,"name":"test","hobby":"\xe6\x89\x93\xe7\xaf\xae\xe7
\x90\x83","age":991}]'

Deserialization

The process of deserialization is similar to serialization, first parsing the serialized data (json) to the native python data type (omitted), and then populating it into a serializer object.

In [29]: data ={"name":"test111","hobby":"drink","age":44}

In [30]: p = ProjectSerializers(data=data)

In [31]: p.is_valid() # check
Out[32]: True
In [33]: s.validated_data # Verified data
Out[34]: OrderedDict([('name', 'test111'), ('hobby', 'drink'), 

Before calling the save() method, you need to implement two methods to complete the creation and modification of the model instance. Override the create and update methods in the parent class in the ProjectSerializer class:

from rest_framework import serializers
from project2s.models import Student

class ProjectSerializers(serializers.Serializer):
    """
    Project serializer
    """
    id = serializers.IntegerField(label='student id', read_only=True)
    name = serializers.CharField(label='Student name')
    hobby = serializers.CharField(label='hobby', allow_null=True, required=False)  # It is allowed to receive null, required=False. This field can be ignored when instantiating an object
    age = serializers.IntegerField(label='Age')
    c_time = serializers.DateTimeField(label='Creation time', read_only=True)

    def create(self, validated_data):
   
        return Student.objects.create(**validated_data) # Returns a new object

    def update(self, instance, validated_data):
        for key, value in validated_data.items():
            setattr(instance, key, value)
        instance.save()
        return instance
In [35]: s.save() # The serializer instance can call save() to return a model instance directly
Out[36]: <Student: name:test111,hobby:drink>

When the data verification fails, you can view the specific information through errors:
give an example:
The name field is not transferred, and the verification result is False

In [9]:  data ={"name":"","hobby":"drink","age":44}

In [10]: p1 = ProjectSerializers(data=data)

In [11]: p1.is_valid()
Out[11]: False

In [12]: p1.error_messages
Out[12]: 
{'required': 'This field is required.',
 'null': 'The field cannot be empty null. ',
 'invalid': 'Invalid data. Look for the dictionary type and get {datatype} . '}

In [13]: p1.errors
Out[13]: {'name': [ErrorDetail(string='This field cannot be empty.', code='blank')]}

Model serializer

Our ProjectSerializer class copies a lot of information from the Project model. RESTframework provides a ModelSerializer, which can automatically create the Serializer class according to the model, making the code more concise.

from rest_framework import serializers
from project2s.models import Student

class ProjectSerializers(serializers.ModelSerializer):
    class Meta:
        model = Student # Specify model
        fields = ['id', 'name', 'hobby', 'age'] # Specify the fields to serialize

You can check all fields of the serializer instance by printing its representation:

In [1]: from project2s.serializers import *

In [2]: s = ProjectSerializers()

In [3]: s
Out[3]: 
ProjectSerializers():
    id = IntegerField(label='ID', read_only=True)
    name = CharField(help_text='Student name', label='Student name', max_length=200, validators=[<UniqueValidator(queryset=Student.objects.all())>])
    hobby = CharField(allow_blank=True, allow_null=True, help_text='hobby', label='hobby', max_length=200, required=False)
    age = IntegerField(allow_null=True, label='Age', max_value=2147483647, min_value=-2147483648, required=False)

The ModelSerializer class is just a shortcut to create the serializer class, automatically determined fields, and a simple default implementation of the create() and update() methods.

Keywords: Operation & Maintenance Docker Container DRF

Added by loweauto on Tue, 23 Nov 2021 22:57:49 +0200