Use deserializer
Use serializer two stages:
- When the client request can be completed using a sequence of data deserialization.
- When the server responds, can be accomplished using the serializer to serialize the data.
Use of the basic sequence
Or a blog post on the database used in the use of
First check out a student objects
from students.models import Student student = Student.objects.get(id=3)
Configured serialized objects
from .serializers import StudentSerializer serializer = StudentSerializer(instance=student)
Get serialized data
Data may be obtained by the serialized data property
serializer.data # {'id': 4, 'name': '盖伦', 'age': 18, 'sex': True, 'description': '德玛西亚'}
Full View Code
from django.views import View from students.models import Student from .serializers import StudentSerializer from django.http.response import JsonResponse class StudentRetrieveView(View): """使用序列化器序列化转换单个模型数据""" def get(self,request,pk): # 获取数据 student = Student.objects.get(pk=pk) # 数据转换[序列化过程] serializer = StudentSerializer(instance=student) print(serializer.data) # 响应数据 return JsonResponse(serializer.data)
If that is to be serialized including a plurality of sets of data query QuerySet, by adding many = True parametric description
class StudentView(View): """使用序列化器序列化转换多个模型数据""" def get(self,request): # 获取数据 student_list = Student.objects.all() # 转换数据[序列化过程] # 如果转换多个模型对象数据,则需要加上many=True serializer = StudentSerializer(instance=student_list,many=True) print( serializer.data ) # 序列化器转换后的数据 # 响应数据给客户端 # 返回的json数据,如果是列表,则需要声明safe=False return JsonResponse(serializer.data,safe=False)
Deserialization
data verification
- When using the serializer to deserialize, you must first validate the data before it can obtain verification of successful data or saved as an object model class.
- Before getting deserialized data, you must call is_valid () method to verify, verify successful return True, otherwise False.
- Verification fails, the object serialization errors attribute acquiring error information returned dictionary containing fields and field errors. If the field is non-error, by modifying the REST framework configuration NON_FIELD_ERRORS_KEY to control the error dictionary keys.
- Successful validation, the sequence of objects by the validated_data acquiring data attributes.
When defining serialization, a sequence of specified types and options of each parameter field, itself a behavior verification.
Create a new sub-application books
python manage.py startapp books
New books in the sub-applications in settings.py in INSTALLED_APPS
INSTALLED_APPS = [
# ...
'ser',
'unser',
]
Definition of a book and the serializer model,
Book model, as follows:
from django.db import models
class Book(models.Model):
"""图书模型"""
title = models.CharField(verbose_name='名称', max_length=20)
pub_date = models.DateField(verbose_name='发布日期')
read = models.IntegerField(verbose_name='阅读量',default=0)
comment = models.IntegerField(verbose_name='评论量', null=True, blank=True)
class Meta:
db_table = "tb_book"
verbose_name="图书"
verbose_name_plural=verbose_name
def __str__(self):
return self.title
Perform data migration, code:
python manage.py makemigrations
python manage.py migrate
BookSerializer serialization, code:
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
"""图书数据序列化器"""
id = serializers.IntegerField(label='ID', read_only=True)
title = serializers.CharField(label='名称', max_length=20)
pub_date = serializers.DateField(label='发布日期', required=False)
read = serializers.IntegerField(label='阅读量', required=False)
comment = serializers.IntegerField(label='评论量', required=False)
By constructing a sequence of objects, and to deserialize data to the data structure parameters, and further verify
from book.serializers import BookSerializer
data = {'pub_date': 123}
serializer = BookSerializer(data=data)
serializer.is_valid() # 返回False
serializer.errors
# {'title': [ErrorDetail(string='This field is required.', code='required')], 'pub_date': [ErrorDetail(string='Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]].', code='invalid')]}
serializer.validated_data # {}
data = {'title': 'python'}
serializer = BookSerializer(data=data)
serializer.is_valid() # True 验证结果返回值
serializer.errors # {} 错误信息
serializer.validated_data # OrderedDict([('btitle', 'python')])
is_valid () method may further exception is thrown if the validation fails serializers.ValidationError, can pass raise_exception = True parameters open, REST framework receives this exception, it returns a response to the HTTP 400 Bad Request distal end.
# Return a 400 response if the data was invalid.
serializer.is_valid(raise_exception=True)
If that was not enough, you need to add custom validation behavior, you can use the following three ways:
validate_ field name
Of the <field_name>
field to verify, as
class BookSerializer(serializers.Serializer):
"""图书数据序列化器"""
...
def validate_title(self, value):
if 'django' not in value.lower():
raise serializers.ValidationError("图书不是关于Django的")
return value
test
from book.serializers import BookSerializer
data = {'title': 'python'}
serializer = BookSerializer(data=data)
serializer.is_valid() # False
serializer.errors
# {'title': [ErrorDetail(string='图书不是关于Django的', code='invalid')]}
validate
When a plurality of fields need to be compared to verify serializer can be defined to validate authentication methods, such as
class BookSerializer(serializers.Serializer):
"""图书序列化器"""
...
def validate(self, attrs):
read = attrs['read']
comment = attrs['comment']
if read < comment:
raise serializers.ValidationError('阅读量小于评论量,不可以通过')
return attrs
test
from book.serializers import BookSerializer
data = {'title': 'about django', 'read': 10, 'comment': 20}
s = BookSerializer(data=data)
s.is_valid() # False
s.errors
# {'non_field_errors': [ErrorDetail(string='阅读量小于评论量', code='invalid')]}
validators
Add validators option parameters in the field, also can add validation behavior, such as
def about_django(value):
if 'django' not in value.lower():
raise serializers.ValidationError("图书不是关于Django的")
class BookSerializer(serializers.Serializer):
"""图书序列化器"""
id = serializers.IntegerField(label='ID', read_only=True)
title = serializers.CharField(label='名称', max_length=20, validators=[about_django])
pub_date = serializers.DateField(label='发布日期', required=False)
read = serializers.IntegerField(label='阅读量', required=False)
comment = serializers.IntegerField(label='评论量', required=False)
image = serializers.ImageField(label='图片', required=False)
test:
from book.serializers import BookSerializer
data = {'title': 'python'}
serializer = BookSerializer(data=data)
serializer.is_valid() # False
serializer.errors
# {'title': [ErrorDetail(string='图书不是关于Django的', code='invalid')]}
Deserialize - save data
After the preceding data is successfully verified, we can use the data to accomplish the serializer deserialization process. This process can be converted into the data model class object.
It can be achieved create()
and update()
to implement two methods.
class BookSerializer(serializers.Serializer):
"""图书数据序列化器"""
...
def create(self, validated_data):
"""新建"""
return Book(**validated_data)
def update(self, instance, validated_data):
"""更新,instance为要更新的对象实例"""
instance.title = validated_data.get('title', instance.title)
instance.pub_date = validated_data.get('pub_date', instance.pub_date)
instance.read = validated_data.get('read', instance.read)
instance.comment = validated_data.get('comment', instance.comment)
return instance
If the time required to return the data object, save data to the database, can be modified as follows
class BookSerializer(serializers.Serializer):
"""图书数据序列化器"""
...
def create(self, validated_data):
"""新建"""
return Book.objects.create(**validated_data)
def update(self, instance, validated_data):
"""更新,instance为要更新的对象实例"""
instance.title = validated_data.get('title', instance.title)
instance.pub_date = validated_data.get('pub_date', instance.pub_date)
instance.read = validated_data.get('read', instance.read)
instance.comment = validated_data.get('comment', instance.comment)
instance.save()
return instance
After achieve the above two methods, when the deserialized data, it can save () method returns an instance of the data object
book = serializer.save()
If you create a serialized object when there is no transmission instance instance, call the save()
method when, Create () is called, the contrary, if the passed instance instance, calling save()
methods when update()
invoked.
from .serializers import BookSerializer
data = {'title': 'python入门指南'}
serializer = BookSerializer(data=data)
serializer.is_valid() # True
serializer.save() # <BookInfo: python入门指南>
from .models import Book
book = Book.objects.get(id=2)
data = {'title': 'django入门指南'}
serializer = BookSerializer(book, data=data)
serializer.is_valid() # True
serializer.save() # <BookInfo: django入门指南>
book.title # 'django入门指南'
Additional information
When the serializer for save () save, may additionally transfer data that can be acquired in the create () and update () in parameter validated_data
# request.user 是django中记录当前登录用户的模型对象 serializer.save(owner=request.user)
The default serialization must pass all required fields, otherwise it will throw an exception verification. But we can use partial parameter to allow some field update
# Update `comment` with partial data serializer = CommentSerializer(comment, data={'content': u'foo bar'}, partial=True)
Model class serializer
After the experimental front, there a doubt that we can not use the serializer corresponding model class in Django? If so, we do not need to control the number of columns of models model's design. Taking into account the cost of the majority of the time the siege lion, DRF provides us ModelSerializer model class serializer to help us quickly create a Serializer class.
ModelSerializer conventional Serializer the same, but provides:
- Automatically generating a series based model class field
- Serializer validators is automatically generated based on model class, such as unique_together
- Includes a default create () and update () implementation
definition
For example, we create a BookSerializer
class BookSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model = Book
fields = '__all__'
- Referring to specify which model-based model
- in which specified fields generated model class field
We can see BookSerializer automatically generated in python manage.py shell in concrete realization
>>> from booktest.serializers import BookSerializer
>>> serializer = BookSerializer()
>>> serializer
BookSerializer():
id = IntegerField(label='ID', read_only=True)
title = CharField(label='名称', max_length=20)
pub_date = DateField(allow_null=True, label='发布日期', required=False)
read = IntegerField(label='阅读量', max_value=2147483647, min_value=-2147483648, required=False)
comment = IntegerField(label='评论量', max_value=2147483647, min_value=-2147483648, required=False)
The specified field
1) Use fields to clear the field, __all__
table name contains all the fields, which can also indicate the specific field, such as
class BookSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model = Book
fields = "__all__"
2) Use exclude can be explicitly ruled out which fields
class BookSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model = Book
exclude = ('pub_date',)
3) Display of the specified attribute, such as:
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ('id', 'title', 'comment', 'read')
4) indicates a read only field
By read_only_fields field to indicate the read-only field, i.e. output only for serializing
class BookSerializer(serializers.ModelSerializer):
"""图书序列化器"""
class Meta:
model = Book
fields = ('id', 'title', 'pub_date', 'read', 'comment')
read_only_fields = ('id', 'read', 'comment')
Additional parameters
We can use extra_kwargs parameters are added to ModelSerializer or amend the option parameter
class BookSerializer(serializers.ModelSerializer):
"""图书序列化器"""
class Meta:
model = Book
fields = ('id', 'title', 'pub_date', 'read', 'comment')
extra_kwargs = {
'read': {'min_value': 0, 'required': True},
'comment': {'min_value': 0, 'required': True},
}
# BookSerializer():
# id = IntegerField(label='ID', read_only=True)
# title = CharField(label='名称', max_length=20)
# pub_date = DateField(allow_null=True, label='发布日期', required=False)
# read = IntegerField(label='阅读量', max_value=2147483647, min_value=0, required=True)
# comment = IntegerField(label='评论量', max_value=2147483647, min_value=0, required=True)