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.