Django中的序列化器
Django 中的序列化器(Serializer)是用于在数据模型(Model)和其他格式(如 JSON)之间进行数据转换的工具。序列化器允许你将数据对象转换为可序列化的格式,以便在网络传输、存储或渲染到模板中使用。
简单来说:就是将从数据库取出的数据进行包装,然后发送给前端。
Serializer
Serializer 是一个基础类,用于手动定义数据序列化和反序列化的过程。你可以继承 Serializer 类并定义字段、验证规则和自定义序列化逻辑。这个类提供了一些基本方法。
实际开发中
公共基础序列化器
首先我们会在公共utils中写好一些基础的Serializers。
1、BaseSerializer 是一个基础的序列化器类,它接收一个对象 obj 作为参数,并提供了一个默认的 to_dict() 方法,返回一个空字典。可以在该类的子类中重写 to_dict() 方法,根据需要自定义数据转换逻辑。
class BaseSerializer(object):
def __init__(self, obj):
self.obj = obj
def to_dict(self):
return {}
2、MetaSerializer 是用于表示分页元数据的序列化器类。它接收当前页 page、总页数 page_count 和总记录数 total_count 作为参数,并提供了一个 to_dict() 方法,将这些元数据转换为字典格式。
class MetaSerializer(object):
""" 分页元数据 """
def __init__(self, page, page_count, total_count, **kwargs):
"""
:param page: 当前页
:param page_count: 总页数
:param total_count: 总记录数
"""
self.page = page
self.page_count = page_count
self.total_count = total_count
def to_dict(self):
return {
'total_count': self.total_count,
'page_count': self.page_count,
'current_page': self.page
}
3、BaseListPageSerializer 是一个封装了分页数据的序列化器类。它接收当前页的对象 page_obj、分页器的对象 paginator 和当前页的数据列表 object_list 作为参数。该类提供了一个 to_dict() 方法,将分页数据传递给MetaSerializer()转换为字典格式。然后将Meta数据和取到的objects封装好一起返回给前端。子类需要重写get_object()传递要取的参数
class BaseListPageSerializer(object):
""" 分页类封装 """
def __init__(self, page_obj, paginator=None, object_list=[]):
"""
:param page_obj: 当前页的对象
:param paginator: 分页器的对象
:param object_list: 当前页的数据列表
"""
self.page_obj = page_obj
self.paginator = paginator if paginator else page_obj.paginator
self.object_list = object_list if object_list else page_obj.object_list
def get_object(self, obj):
""" 对象的内容,子类重写 """
return {}
def to_dict(self):
page = self.page_obj.number
page_count = self.paginator.num_pages
total_count = self.paginator.count
meta = MetaSerializer(page=page, page_count=page_count, total_count=total_count).to_dict()
objects = []
for obj in self.object_list:
objects.append(self.get_object(obj))
return {
'meta': meta,
'objects': objects
}
继承基础序列化器
1、继承列表序列化器
-
SightListSerializer是继承自BaseListPageSerializer的具体序列化器类,用于序列化景点列表数据。
-
在
SightListSerializer中,重写了父类的get_object()方法。该方法接收一个景点对象obj,并将其转换为字典格式的数据。
-
在
get_object()方法中,根据具体的需求,从景点对象obj中提取需要的字段,并将它们添加到一个字典中。在示例代码中,提取了景点的id、name、main_img(主要图片的 URL)、score、province、min_price和city字段,并设置了comment_count为固定值 0(评论数量暂时无法获取)。 -
通过这种方式,
SightListSerializer将每个景点对象转换为包含特定字段的字典格式数据。在to_dict()方法中,通过调用get_object()方法处理当前页的每个景点对象,并将转换后的数据添加到objects列表中。最后,将分页元数据和对象列表组装成一个字典,并返回结果。
class SightListSerializer(BaseListPageSerializer):
"""景点列表"""
def get_object(self, obj):
return {
'id': obj.id,
'name': obj.name,
'main_img': obj.main_img.url,
'score': obj.score,
'province': obj.province,
'min_price': obj.min_price,
'city': obj.city,
# TODO 评论数量暂时无法获取
'comment_count': 0
}
对应接口
class SightListView(ListView):
""" 景点列表 """
# 每页放5条数据
paginate_by = 5
def get_queryset(self):
""" 重写查询方法 """
query = Q(is_valid=True)
# 1. 热门景点
is_hot = self.request.GET.get('is_hot', None)
if is_hot:
query = query & Q(is_hot=True)
# 2. 精选景点
is_top = self.request.GET.get('is_top', None)
if is_top:
query = query & Q(is_top=True)
# TODO 3. 景点名称搜索
queryset = Sight.objects.filter(query)
return queryset
def render_to_response(self, context, **response_kwargs):
print(context)
page_obj = context['page_obj']
if page_obj is not None:
data = serializers.SightListSerializer(page_obj).to_dict()
return http.JsonResponse(data)
else:
return NotFoundJsonResponse()
2、继承基础序列化器
-
SightDetailSerializer是继承自BaseSerializer的具体序列化器类,用于序列化景点详情数据。 -
在
SightDetailSerializer中,重写了父类的to_dict()方法。该方法将景点对象self.obj的字段转换为字典格式的数据。 -
在
to_dict()方法中,根据具体的需求,从景点对象self.obj中提取需要的字段,并将它们添加到一个字典中。在示例代码中,提取了景点的id、name、desc、img(横幅图片的 URL)、content、score、province、min_price、city、area和town字段,并设置了comment_count为固定值 0(评论数量暂时无法获取)。
class SightDetailSerializer(BaseSerializer):
"""景点详情"""
def to_dict(self):
obj = self.obj
return {
'id': obj.id,
'name': obj.name,
'desc': obj.desc,
'img': obj.banner_img.url,
'content': obj.content,
'score': obj.score,
'province': obj.province,
'min_price': obj.min_price,
'city': obj.city,
'area': obj.area,
'town': obj.town,
# TODO 评论数量暂时无法获取
'comment_count': 0
}
对应接口
class SightDetailView(DetailView):
""" 景点详情 """
#DetailView会自动匹配pk
def get_queryset(self):
return Sight.objects.all()
def render_to_response(self, context, **response_kwargs):
page_obj = context['object']
if page_obj is not None:
if page_obj.is_valid == False:
return NotFoundJsonResponse()
data = serializers.SightDetailSerializer(page_obj).to_dict()
return http.JsonResponse(data)
return NotFoundJsonResponse()

浙公网安备 33010602011771号