예제 #1
0
    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
예제 #2
0
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))
예제 #3
0
 def get_serializer_class(self):
     model = get_user_model()
     return create_serializer_class(model)