def get_serializer_class(self, expand_fields=None): """动态的获取序列化类 - 如果没有嵌套字段,则动态创建最简单的序列化类 - 如果有嵌套字段,则动态创建引用字段的嵌套序列化类 """ # FIXME: 这里只有做是为了使用 django-rest-swagger,否则会报错,因为 swagger 还是很笨 expand_fields = getattr(self, 'expand_fields', None) # FIXME: 这里设置了一个默认值,是为了避免 swagger 报错 model = getattr(self, 'model', get_user_model()) tree_data = getattr(self, 'tree_data', None) # 如果没有展开字段,则直接创建模型对应的序列化类 if not expand_fields: serializer_class = create_serializer_class( model, tree_structure=tree_data, action=self.action, end_slug=self.end_slug, ) else: # 如果有展开字段,则创建嵌套的序列化类 serializer_class = multiple_create_serializer_class( model, expand_fields, tree_structure=tree_data, action=self.action, end_slug=self.end_slug, display_fields=self.get_display_fields(), ) return serializer_class
def reverse_many_to_many(instance, field, data): """ 处理反向多对多关系的数据 Params: instance object 对象 field object 反向的字段 data list 反向的模型字典列表数据 """ # 反向关系的数据必须是数组 if not isinstance(data, list): raise exceptions.BusinessException( error_code=exceptions.PARAMETER_FORMAT_ERROR, error_data=f'{field.name}: {data} 只能是列表', ) # TODO: 如果使用了自定义的中间表,此种业务暂时不做处理 # TODO: 支持自定义中间表,如果非单纯中间表让它自行报异常,中间表必填值以后可以考虑使用 through_defaults # if field.through_fields: # return model = field.related_model related_name = meta.get_accessor_name(field) reverse_manager = getattr(instance, related_name, None) if related_name else None if not data: # 传入数据为空的场景 # 更新操作,如果传入空的数据,则清除掉此对象所有的数据 if reverse_manager: reverse_manager.clear() return # 传入数据不为空的情况下 pk_field_name = model._meta.pk.name # 迭代处理反向数据,这个时候还没有处理数据和对象的关系 reverse_object_list = set() for item_value in data: if isinstance(item_value, dict): if pk_field_name not in item_value: # 创建反向模型的数据 serializer = create_serializer_class(model)(data=item_value) serializer.is_valid(raise_exception=True) item_instance = serializer.save() else: # 更新反向模型的数据 item_instance = model.objects.filter( **{pk_field_name: item_value[pk_field_name]} ).first() if not item_instance: raise exceptions.BusinessException( error_code=exceptions.OBJECT_NOT_FOUND, error_data=f'{pk_field_name}: {item_value} 指定的主键找不到对应的数据', ) serializer = create_serializer_class(model)( instance=item_instance, data=item_value, partial=True ) serializer.is_valid(raise_exception=True) serializer.save() reverse_object_list.add(item_instance.pk) else: reverse_object_list.add(item_value) # 处理数据和 instance 之间的关系 if reverse_manager: reverse_manager.set(list(reverse_object_list))
def get_serializer_class(self): model = get_user_model() return create_serializer_class(model)