drf framework serialization and deserialization

Keywords: Python Attribute Django Database

0903 self-summary

drf framework serialization and deserialization

from rest_framework import serializers

I. My own classification of serialization and deserialization

Front-end and back-end interactions include get,post,puch,put,deleter

Where serialized get is used

Use the remaining four of back serialization

II. Use of serialization

1. First, we need to define a class inheriting serializers.Serializer one by one according to the model we defined.

class UserSerializer(serializers.Serializer):
    username = serializers.CharField()
    #Unneeded fields = serializers.CharField(write_only=True)
    sex = serializers.IntegerField()

    gender = serializers.SerializerMethodField()
    def get_gender(self, user_obj):
        return user_obj.get_sex_display()
    
    icon = serializers.SerializerMethodField() #Serializer Method Field is a custom field
    def get_icon(self, user_obj):
        icon_url = 'http://127.0.0.1:8000{}{}'.format(settings.MEDIA_URL, user_obj.icon)
        return icon_url

Custom fields, take the gander field as an example in models

SEX_CHOICES = [
    (0, 'male'),     #In choices selection, the former in parentheses represents the filled-in value, and the latter represents the corresponding value.
    (1, 'female'),
]
# For the fields of choices, the mapping relation get_field name_display() after getting the value
sex = models.IntegerField(choices=SEX_CHOICES, default=0)
def get_gender(self, user_obj):
    return user_obj.get_sex_display()
get_Fixed Writing Based on get Request
 The def get_model class has fields (self,obj):
    # Logical Processing
    return modified code

Need to serialize fields

  • The field in the class we defined must exist in the model class without any processing.
  • Attribute names participating in serialization must be the same as those of model classes
  • Only appear in serialization but not in deserialization. We add read-only attribute read_only=True
  • If we define a field type in the Serializer class as Serializer MethodField and a custom field type without observing the field in the class, the field must exist in the model class.

No need to serialize fields

  • Property fields that do not need to be serialized do not need to be declared in serialized classes
  • Setting a write-only attribute write_only=True in a serialized class without serialized property fields

2. In views View

from rest_framework.views import APIView
class UserAPIView(APIView):
     def get(self, request, *args, **kwargs):
        user_obj = models.User.objects.all().frist
        user_obj_data = '''Our custom Serializer class'''(user_obj).data
        return APIResponse(0, 'ok', results=user_obj_data)
  • Getting objects in models
  • Our custom Serilizer class passes in the objects in the models and then.
  • If the objects in the models are multiple Serializer s passing in to the objects in the models, many=True needs to pass in this parameter as well.
  • The default for this parameter is False. We don't need to pass in many when serializing a single parameter.
  • Serialized data can be a single-column set of multiple objects of the state User class, not a multi-column set.

Note:

  • Single column set [a, b, c...] | {a, b, c....} | (a, b, c....)| QuerySet
  • Multi-column sets {k1:v1,k2:v2...}

Use of triple deserialization

1. First, we need to define a class inheriting serializers.Serializer one by one according to the model we defined.

class UserDeserializer(serializers.Serializer):
    username = serializers.CharField(
        min_length=3,
        error_messages={
            'min_length': 'User name is too short'
        }
    )
    password = serializers.CharField(
        min_length=3,
        error_messages={
            'min_length': 'Password too short'
        }
    )
    re_password = serializers.CharField(
        min_length=3,
        required=True,
        error_messages={
            'min_length': 'Confirmation password is too short',
            'required': 'Confirmation password cannot be empty'
        }
    )

Screening conditions are added to deserialization of serialization definitions

Note: If the field value of a class is applied to deserialization, we can add write_only=True to the attribute of its field.

The fields mentioned in it must be passed in

The commonly used approximation conditions are somewhat similar to those of from components in django:

  • Attributes of error_messages error information
  • Is required empty
  • max_length is the longest
  • min_length is the shortest
  • invalid format

Local hook

class UserDeserializer(serializers.Serializer):
    .......
    def validate_Field name(self,value):
        #code block
        if The situation is unsatisfactory:
            raise serializers.ValidationError('Abnormal information') #throw
            return value
        #That is to say, the field data is processed twice.

global hook

 class UserDeserializer(serializers.Serializer):
    .......
    def validate(self, attrs):
        #attrs is a dictionary-like collection of all fields
        #We want one of these fields
        attrs.get('Field name')
        return attrs
       # The final result throws an exception or returns attrs

2. Additional use of content

We have to add a create method to the Serializer class

class UserDeserializer(serializers.Serializer):
    .......
    def create(self, validated_data):
        try:
            return modles Classes in.objects.create(**validated_data)
        except:
            raise IOError('Database Input Failure')

We need to customize an APIResponse and inherit the Response in rest_framework to use it directly.

Customize APIResponse and recommend customization

from rest_framework.response import Response
"""
Response({
    'status': 0,
    'msg': 'ok',
    'results': [],
    'token': ''
}, headers={}, status=200, content_type="")

APIResponse(0, 'ok', results, status, headers, content_type)
"""

class APIResponse(Response):
    def __init__(self, data_status, data_msg, results=None,
                 status=None, headers=None, content_type=None, **kwargs):
        data = {
            'status': data_status,
            'msg': data_msg
        }
        if results is not None:
            data['results'] = results
        data.update(kwargs)
        super().__init__(data=data, status=status, headers=headers, content_type=content_type)

Settings in View Functions

class UserAPIView(APIView):
    def post(self, request, *args, **kwargs):  #Usually post requests
        request_data = request.data
        user_ser = '''Our custom Serializer class'''(data=request_data) #Input request.data
        
        
        if user_ser.is_valid():  # Custom Processing Check Successful Logic
            user_obj = user_ser.save()
            return APIResponse(0, 'ok',
                results=serializers.UserSerializer(user_obj).data
            )
        else:  # Custom return error message
            return APIResponse(1, 'failed', results=user_ser.errors)

3. Content modification and use

We have to add a create method to the Serializer class

class UserDeserializer(serializers.Serializer):
         .......
    def update(self, instance, validated_data):
        # instance customizes the incoming raw data to be updated (pk | obj | queryset)
        # New data after validated_data validation
        # External de-serialization of instance values into custom identity decisions to be updated
        instance.update(**validated_data)
        return instance.first()

Settings in View Functions

Monolithic reform

class UserV2APIView(APIView):
    
    def put(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if not pk:
            return APIResponse(1, 'pk error')

        user_query = models.User.objects.filter(pk=pk, is_delete=False)
        if not user_query:
            return APIResponse(1, 'user error')

        # First: user_query completes data updates
        # user_query = models.User.objects.filter(pk=pk)
        # user_query.update(**kwargs)

        # Second: user_obj completes data updates
        # user_obj = models.User.objects.filter(pk=pk).first()  # type: models.User
        # user_obj.username = 'new_username'
        # ...
        # user_obj.save()
  

       #The instance here must be passed in (pk | obj | queryset)
        request_data = request.data
        user_ser = serializers.UserV2Serializer(instance=user_query, data=request_data)
        if user_ser.is_valid():
            # The return value of save is determined by the customized return value within update
            user_obj = user_ser.save()
            return APIResponse(0, 'ok',
                results=serializers.UserV2Serializer(user_obj).data
            )
        else:
            return APIResponse(1, 'failed', user_ser.errors)

Single deletion or modification

Now the data is very important. Normally, it will not be deleted. It will only be a tag field, its essence or local update.

    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if not pk:
            return APIResponse(1, 'pk error')
        user_obj = models.User.objects.filter(pk=pk, is_delete=False).first()
        if not user_obj:
            return APIResponse(1, 'Delete failed')
        user_obj.is_delete = True
        user_obj.save()
        return APIResponse(0, 'Successful deletion')

model field revision and time zone revision

model.py

    create_time = models.DateTimeField(auto_now_add=True, null=True)
    is_delete = models.BooleanField(default=False)

setting.py

Time zone related settings

LANGUAGE_CODE = 'zh-hans'   #zh-Hans is simplified Chinese zh-Hant is traditional Chinese.

TIME_ZONE = 'Asia/Shanghai'  #Shanghai Time

USE_I18N = True   #Internationalization Support I18N

USE_L10N = True

USE_TZ = False   #When USE_TZ is set to True,Django will use the default time zone set by the system, namely America/Chicago, at which time TIME_ZONE will not work regardless of whether it is set or not.

Note:

USE_TZ is True,TIME_ZONE does not work with or without settings.

Posted by scarface222 on Wed, 04 Sep 2019 23:46:41 -0700