Django rest framework
什么时候须要用 many 参数呢?
- 当结构序列化的时候,传递的参数的 QuerySet 实例,就须要用 many=True 参数,即使 QuerySet 长度为 0 或者长度为 1
- 当结构序列化的时候,传递的参数的某个模型实例(内置的 User 实例,或者自定义的模型实例),就须要用 many=false 参数
源码解析
class BaseSerializer(Field):
def __init__(self, instance=None, data=empty, **kwargs):
self.instance = instance
if data is not empty:
self.initial_data = data
self.partial = kwargs.pop('partial', False)
self._context = kwargs.pop('context', {})
kwargs.pop('many', None)
super().__init__(**kwargs)
def __new__(cls, *args, **kwargs):
if kwargs.pop('many', False):
return cls.many_init(*args, **kwargs)
return super().__new__(cls, *args, **kwargs)
@classmethod
def many_init(cls, *args, **kwargs):
allow_empty = kwargs.pop('allow_empty', None)
child_serializer = cls(*args, **kwargs)
list_kwargs = {'child': child_serializer,}
if allow_empty is not None:
list_kwargs['allow_empty'] = allow_empty
list_kwargs.update({key: value for key, value in kwargs.items()
if key in LIST_SERIALIZER_KWARGS
})
meta = getattr(cls, 'Meta', None)
list_serializer_class = getattr(meta, 'list_serializer_class', ListSerializer)
return list_serializer_class(*args, **list_kwargs)
当应用如下的语句进行序列化操作的时候。serializer = TweetSerializer(queryset, many=True)
queryset
会被赋值给 BaseSerializer
对应的构造方法 def __init__(self, instance=None, data=empty, **kwargs):
中的 instance
参数。
当 instance 参数承受的是 QuerySet 实例,就须要加 many=True,如果 instance 承受的某个模型实例,例如 TweetModel
class TweetAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView
):
queryset = TweetModel.objects.all()
serializer_class = TweetCreateSerializer
def get(self, request: Request):
return self.list(request)
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
serializer = TweetSerializer(queryset, many=True)
return Response(serializer.data)
def post(self, request: Request):
return self.create(request)
class TweetModel(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
title = models.CharField(max_length=32, verbose_name='题目')
content = models.TextField(verbose_name='注释')
photos = models.ManyToManyField(Photo, blank=True)
likes_count = models.BigIntegerField(default=0, null=True)
comments_count = models.BigIntegerField(default=0, null=True)
read_count = models.BigIntegerField(default=0, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
index_together = (('user', 'created_at'),)
def __str__(self):
# 这里是你执行 print(tweet instance) 的时候会显示的内容
return '{} {}: {}'.format(self.created_at, self.user, self.content)