Django rest frameworkpython
何時須要用many參數呢?post
源碼解析rest
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接受的某個模型實例,例如TweetModelcode
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)