Specific Use of drf Serializer serializer

  • 2021-11-13 08:36:10
  • OfStack

Directory 1. Serializer-serializer
2. Use of serializers
Simple use
Advanced use
source
**SerializerMethodField( ) **
General parameter
3. Validation of deserialized data
Field property local hook
Global hook
validators
4. Serializer manipulates data
Query all
Query single
Add data
Modify data
Delete data
5. Model class serializer
6. Source code analysis many=True

1. Serializer-serializer

Serialization, the serializer will turn the model object into a dictionary, and after response, it will become an JSON string Deserialization: The data sent by the client becomes a dictionary after request, and the serializer can turn the dictionary into a model Deserialization: Complete the data verification function

2. Use of serializers

The use of serializers is divided into two stages:

Serializer can be used to deserialize data when requested by client. Serializer can be used to serialize data when the server responds.

Simple use

1. Create a table model


from django.db import models

class Books(models.Model):
    title = models.CharField(verbose_name=' Book title ', max_length=32)
    publish = models.CharField(verbose_name=' Publishing house ', max_length=32)
    price = models.DecimalField(verbose_name=' Price ', max_digits=5, decimal_places=2)

2. Create a new py file, write a serialized class, and inherit Serializer

3. Write the field to be serialized in the class. If you want to serialize that field, write that field in the class


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField()

4. Use in the view class, import-"instantiate to get serialized objects, and pass the objects to be serialized into

5. Serialized Object. data-"Is a Dictionary

6. Return the dictionary. If you don't use Response provided by rest_framework, you have to use JsonResponse


from rest_framework.views import APIView
from rest_framework.request import Request
from app01.models import Books
from app01.ser import BooksSerializer

class BookView(APIView):
    def get(self, request, pk):
        #  Response information 
        response_msg = {'status': 200, 'message': ' Query succeeded '}
        #  Gets the object to serialize 
        book = Books.objects.filter(pk=pk).first()
        #  Pass whoever wants to serialize to the serialization class 
        book_ser = BooksSerializer(book)
        # book_ser.data ---"Serialize object .data ---"is the serialized dictionary 
        #  Add query results to response information 
        response_msg['data'] = book_ser.data
        return Response(response_msg)
    
 # urls.py
re_path(r'^book/(?P<pk>\d+)/', views.BookView.as_view()),

7. If you want to serialize the query set queryset containing multiple pieces of data, you can add the many=True parameter


from rest_framework.views import APIView
from rest_framework.response import Response
from app01.models import Books
from app01.ser import BooksSerializer


class BooksView(APIView):
    def get(self, request):
        #  Response information 
        response_msg = {'status': 200, 'message': ' Query succeeded '}
        books = Books.objects.all()
        #  Pass whoever wants to serialize to the serialization class 
        book_ser = BooksSerializer(books, many=True)
        # book_ser.data ---"Serialize object .data ---"is the serialized dictionary 
        #  Add query results to response information 
        response_msg['data'] = book_ser.data
        return Response(response_msg)

# urls.py
re_path(r'^books/', views.BookView.as_view()),

Advanced use

source

1. You can modify the field name


class BooksSerializer(serializers.Serializer):
    xxx = serializers.CharField(source='title')  #  Equivalent to-" xxx = Books.title
      
#  Response 
{
    "status": 200,
    "message": " Query succeeded ",
    "data": {
        "xxx": " Patriarch of the Magic Way "    ---"The field name of the response has been modified 
    }
}

2. You can query across tables


class BookSerializer(serializers.Serializer):
    publish_email = serializers.CharField(source='publish.email')
    #  Equivalent to-" publish_email = Book.publish.email  Connected table query publish Tabular email Field 
    
    
#  Response 
{
    "status": 200,
    "message": " Query succeeded ",
    "data": {
        "publish_email": "modao@163.com"
    }
}

3. You can execute methods


# models.py
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.IntegerField()
    pub_date = models.DateTimeField()
    publish = models.ForeignKey("Publish", on_delete=models.CASCADE, null=True)
    authors = models.ManyToManyField("Author")

    def func(self):
        return '666666'

    
# ser.py
class BookSerializer(serializers.Serializer):
    msg = serializers.CharField(source='func')
    # msg = Book.func   --"Call Book Class in the func() The return value of the method 
    
    
#  Response 
{
    "status": 200,
    "message": " Query succeeded ",
    "data": {
        "msg": "666666"
    }
}

**SerializerMethodField( ) **

It needs to have a matching method named get_ field name, and the return value is what you want to display


class BookSerializer(serializers.Serializer):
    authors = serializers.SerializerMethodField()

    def get_authors(self, instance):
        # instance  -"  Book Object 
        authors = instance.authors.all()    #  Take out all authors 
        author_list = []
        for author in authors:
            author_list.append({'name': author.name, 'age': author.age})
        return author_list

General parameter

read_only: (read-only) indicates that this field is only used for serialized output. The default is False. If it is set to True, this field can be seen in the response. When modifying, it is not necessary to pass this field

write_only: (Write only) indicates that this field is only used for deserialization input. The default is False. If it is set to True, this field cannot be seen in the response. When modifying, this field needs to be passed


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField(read_only = True)  #  You can see the change field in the response, and you don't need to pass the value for modification 
    publish = serializers.CharField(write_only = True) #  You can't see the change field in the response, so you need to pass the value for modification 
    price = serializers.DecimalField()

There are also parameters as follows:

required indicates that this field must be entered during deserialization, default True Default values used when default deserialization allow_null indicates whether this field allows passing in None, which defaults to False validators the validator used by this field error_messages Dictionary Containing Error Numbers and Error Messages

3. Validation of deserialized data

When the serializer is used to deserialize the data, the data needs to be validated, and only the validated data can be saved as a model class object

The data to be verified is passed into the serializer and instantiated: obj = BooksSerializer (data = request. data), and the is_valid () method is called to verify, and True is returned after successful verification and False is returned after failure.

Failed, the error message can be obtained through the errors of the serializer object (dictionary)

Success, the validated_data property of the public serialization object can be obtained.

Validation methods are: local hook, global hook, validators, and serialization type and field property are also

Field properties

max_length Maximum Length min_lenght Minimum Length allow_blank is null allowed trim_whitespace Truncate white space characters max_value Minimum min_value Max

Local hook

Create a local hook in the serializer class: validate_ field name and receive 1 parameter


# ser.py
class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    
    #  Local hook pair price Field check 
    def validate_price(self, data):
        if float(data) > 20:
            #  If the verification is successful, it will pass 
            return data
        else:
            #  Throw an exception if the verification fails 
            raise ValidationError(' The price is too low ')

Global hook

Global hook: validate (), takes 1 parameter,

Compare and validate multiple fields at the same time


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField()

0

validators

Use validators= [func] of the field to verify


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField()

1

4. Serializer manipulates data

Query all


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField()

2

Query single


# views.py
class BookView(APIView):
    def get(self, request, pk):
        #  Response information 
        response_msg = {'status': 200, 'message': ' Query succeeded '}
        #  Gets the object to serialize 
        book = Books.objects.filter(pk=pk).first()
        #  Pass whoever you want to serialize to the serializer 
        book_ser = BooksSerializer(instance=book)
        # book_ser.data ---"Serialize object .data ---"is the serialized dictionary 
        #  Add query results to response information 
        response_msg['data'] = book_ser.data
        return Response(response_msg)
    
# urls.py
re_path(r'^book/(?P<pk>\d+)/', views.BookView.as_view()),

Add data

Adding data requires overriding the create () method in the serializer:

Note that if an instance instance is not passed, create () is called when the save () method is called, whereas if an instance instance is passed, update () is called when the save () method is called.


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField()

4

Modify data

Modifying the data requires overriding the update () method in the serializer:


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField()

5

Delete data


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField()

6

5. Model class serializer

DRF provides an ModelSerializer model class serializer to help us quickly create an Serializer class.

The ModelSerializer is identical to the regular Serializer, but provides:

Automatically Generate 1 Series Fields Based on Model Classes Automatically generate validators for Serializer based on model classes, such as unique_together Contains the default create () and update ().

Example:


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField()

7

Field operation

1. You can use fields to specify the fields, and __all__ means to include all the fields, which fields- > fields = ('title','price')

2. exclude indicates that those fields are excluded and cannot be written from fields1- > exclude = ('price',)

3. Additional parameters extra_kwargs, adding additional parameters to the field


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book        #  Indicates which model class to refer to 
        fields = '__all__'  #  For those fields of the model class 
  
        #  Similar to   title = serializers.CharField(read_only = True)
        extra_kwargs = {
            'title': {'read_only': True},
        }

6. Source code analysis many=True

When we need to query multiple pieces of data, we need to pass many=True when instantiating the serializer


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField()

9

Related articles: