示例#1
0
    def update(self, request, *args, **kwargs):
        # 获取当前要修改的图片对象
        instance = self.get_object()

        # 接收
        name = request.data.get('name')
        first_letter = request.data.get('first_letter')
        logo = request.data.get('logo')

        # 验证
        if not all(['name', 'first_letter']):
            return Response({'detail:'数据不完整'}, status=400)
        # 处理
        # 1.fdfs:删除旧图片,上传新图片
        if logo:
            # 如果用户上传图片则修改
            image_client = Fdfs_client(settings.FDFS_CLIENT_CONF)
            # 删除===>instance.logo.name===>获取图片的名称字符串
            image_client.delete_file(instance.logo.name)
            # 上传
            data = image_client.upload_by_buffer(logo.read())
            instance.logo = data.get("Remote file_id")
            instance.name = name
            instance.first_letter = first_letter
        else:
            instance.name = name
            instance.first_letter = first_letter
        # 2.保存对象
        instance.save()

        # 响应
        serializer = self.get_serializer(instance)
        return Response(serializer.data, status=201)
示例#2
0
    def update(self, request, *args, **kwargs):

        instence = ModelViewSet.get_object(self)

        sku_ID = request.data.get('sku')
        image = request.data.get('image')

        if not all([sku_ID]):
            return Response({'detail':'数据不完整'},status=400)

        if image:
            image_client = Fdfs_client(settings.FASTDFS_PATH)


            image_client.delete_file(instence.image.name)


            data = image_client.upload_by_buffer(image.read())
            instence.image = data.get('Remote file_id')

        instence.sku_id = sku_ID
        instence.save()

        serializer = self.get_serializer(instence)
        return Response(serializer.data,status=200)
示例#3
0
    def update(self, request, *args, **kwargs):
        # 获取当前要修改的图片对象
        instance = self.get_object()

        # 接收
        sku_id = request.data.get('sku')
        image = request.data.get('image')

        # 验证
        if not all([sku_id]):
            return Response({'detail:'数据不完整'}, status=400)

        # 处理
        # 1.fdfs:删除旧图片,上传新图片
        if image:
            # 如果用户上传图片则修改
            image_client = Fdfs_client(settings.FDFS_CLIENT_CONF)
            # 删除===>instance.image.name===>获取图片的名称字符串
            image_client.delete_file(instance.image.name)
            # 上传
            data = image_client.upload_by_buffer(image.read())
            instance.image = data.get("Remote file_id")

        # 2.修改对象
        instance.sku_id = sku_id
        instance.save()

        # 响应
        serializer = self.get_serializer(instance)
        return Response(serializer.data, status=201)
示例#4
0
    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        sku = instance.sku
        image_url = instance.image.name
        try:
            # 删除文件
            client = Fdfs_client(settings.FDFS_CLIENT_CONF)
            client.delete_file(image_url)
        except:
            pass
        with transaction.atomic():
            sid = transaction.savepoint()
            try:
                instance.delete()
                # 如果删除的图片,是sku的默认图片
                if sku.default_image.name == image_url:
                    # 查询sku的所有图片
                    images = sku.images.all()
                    if images:
                        # 将第一个作为默认图片
                        sku.default_image = images[0].image
                    else:
                        sku.default_image = None
                    sku.save()
            except Exception as e:
                transaction.savepoint_rollback(sid)
                raise serializers.ValidationError('图片删除失败')
                # raise e
            else:
                transaction.savepoint_commit(sid)

                generate_detail_html.delay(sku.id)

                return Response(status=204)
示例#5
0
 def destroy(self, request, *args, **kwargs):
     instance = self.get_object()
     client = Fdfs_client(settings.FDFS_CLIENT_CONF)
     try:
         client.delete_file(instance.logo.name)
     except Exception as e:
         pass
     instance.delete()
     return Response(status=HTTP_201_CREATED)
示例#6
0
 def delete(self, name):
     """
     name:文件id
     :param name:
     :return:
     """
     client = Fdfs_client(self.client_conf)
     # 删除FDFS中存储的图片
     client.delete_file(name)
示例#7
0
 def destroy(self, request, *args, **kwargs):
     instance = self.get_object()
     logo_old = instance.logo.name
     client = Fdfs_client(settings.FDFS_CLIENT_CONF)
     try:
         client.delete_file(logo_old)
     except:
         pass
     response = super().destroy(request, *args, **kwargs)
     return response
示例#8
0
    def destroy(self, request, *args, **kwargs):
        # 查询当前对象
        instance = self.get_object()
        image_client = Fdfs_client(settings.FDFS_CLIENT_CONF)
        # 删除===>instance.logo.name===>获取图片的名称字符串
        image_client.delete_file(instance.image.name)
        # 删除图片
        instance.delete()

        # 响应
        return Response(status=204)
示例#9
0
    def destroy(self, request, *args, **kwargs):

        instance = self.get_object()

        image_client = Fdfs_client(settings.FASTDFS_PATH)

        if instance.image.name :
            image_client.delete_file(instance.image.name)
        else:
            pass
        instance.delete()

        return Response(status=200)
示例#10
0
    def update(self, request, *args, **kwargs):

        # 1.接收参数
        """
           请求体的参数:<QueryDict: {'sku': ['2'], 'image': [<InMemoryUploadedFile: gouzi.png (image/png)>]}>
           kwargs: {'pk': '51'}
        """
        sku_id = request.data.get('sku')
        data = request.FILES.get('image')
        img_id = kwargs.get('pk')

        # 2.校验参数
        try:
            sku = SKU.objects.get(pk=sku_id)
        except SKU.DoesNotExist:
            return Response({'message': 'sku is not found'},
                            status=status.HTTP_404_NOT_FOUND)

        try:
            pic = SKUImage.objects.get(pk=img_id)
        except SKUImage.DoesNotExist:
            return Response({'message': 'image is not found'},
                            status=status.HTTP_404_NOT_FOUND)

        # 3.修改图片
        client = Fdfs_client(settings.FASTDFS_PATH)
        # 3.1 先删除 fsatdfs 老图片
        client.delete_file(pic.image.name)

        # 3.2 再上传 新图片
        result = client.upload_by_buffer(data.read())

        # 4.判断 修改完毕的状态
        if result['Status'] != 'Upload successed.':
            return Response({'messsage': '图片上传失败!'},
                            status=status.HTTP_403_FORBIDDEN)

        # 5.改SKUImage数据
        upload_img_url = result['Remote file_id']
        pic.image = upload_img_url
        pic.save()

        # 6.页面静态化
        get_detail_html.delay(sku_id)

        return Response({
            "id": pic.id,
            "sku": sku.id,
            "image": pic.image.url
        },
                        status=201)
示例#11
0
 def delete(self, name):
     '''删除文件'''
     # 获取storage client 对象
     client = Fdfs_client(self.fdfs_client_conf)
     # 删除文件
     print('delete:', name)
     ret = client.delete_file(name)
     print(ret)
示例#12
0
 def delete(self, name):
     cli = Fdfs_client(self.conf_path)
     if not isinstance(name, bytes):
         name = name.encode()
     try:
         result = cli.delete_file(name)
     except FDFSError as e:
         raise errors.Error(errmsg=f'从FastDFS删除文件{name}失败:') from e
     logger.debug(f'FastDFS delete: {result}')
     if result[0] != 'Delete file successed.':
         raise errors.Error(errmsg=f'FastDFS删除文件{name}失败: {result}')
示例#13
0
    def destroy(self, request, *args, **kwargs):

        # 1.接收参数
        img_id = kwargs['pk']

        # 2.校验
        try:
            pic = SKUImage.objects.get(pk=img_id)
        except SKUImage.DoesNotExist:
            return Response({'message': 'image not found'}, status=404)

        # 3.fastDFS删除图片
        client = Fdfs_client(settings.FASTDFS_PATH)
        client.delete_file(pic.image.name)

        # 4.删除image数据库数据
        pic.delete()

        # 5.返回响应
        return Response(status=204)
示例#14
0
 def update(self, request, *args, **kwargs):
     instance = self.get_object()
     # fast = FastDFSStorage()
     # url = fast.save(name=None, content=request.FILES.get('image'))
     client = Fdfs_client(settings.FDFS_CLIENT_CONF)
     try:
         client.delete_file(instance.image.name)
     except Exception as e:
         pass
     result = client.upload_by_buffer(request.FILES.get('image').read())
     if result.get('Status') != 'Upload successed.':
         raise Exception('上传文件到FDFS系统失败')
     url = result.get('Remote file_id')
     instance.image = url
     instance.save()
     return Response(
         {
             "id": instance.id,
             "sku": instance.sku_id,
             "image": instance.image.url
         },
         status=HTTP_201_CREATED)
示例#15
0
    def delete(self, name):
        """name:要删除文件的id"""
        client = Fdfs_client(self.client_conf)

        print(name)

        # 删除FDFS中存储的图片
        try:
            res = client.delete_file(name)
        except Exception as e:
            print(e)
        else:
            print('删除成功')
示例#16
0
 def update(self, request, *args, **kwargs):
     instance = self.get_object()
     name = request.data.get('name')
     first_letter = request.data.get('first_letter')
     logo = request.data.get('logo')
     logo_old = instance.logo.name
     if not all([name, first_letter, logo]):
         raise serializers.ValidationError('数据不全')
     client = Fdfs_client(settings.FDFS_CLIENT_CONF)
     ret = client.upload_appender_by_buffer(logo.read())
     if ret.get('Status') != 'Upload successed.':
         return Response('图片上传失败')
     image_url = ret.get('Remote file_id')
     # 保存信息
     instance.name = name
     instance.first_letter = first_letter
     instance.logo = image_url
     instance.save()
     # 删除旧的商标
     client.delete_file(logo_old)
     serializer = self.get_serializer(instance)
     return Response(serializer.data, status=201)
示例#17
0
 def update(self, request, *args, **kwargs):
     instance = self.get_object()
     client = Fdfs_client(settings.FDFS_CLIENT_CONF)
     try:
         client.delete_file(instance.logo.name)
     except Exception as e:
         pass
     result = client.upload_by_buffer(request.FILES.get('logo').read())
     if result.get('Status') != 'Upload successed.':
         raise Exception('上传文件到FDFS系统失败')
     url = result.get('Remote file_id')
     instance.logo = url
     instance.name = request.data.get('name')
     instance.first_letter = request.data.get('first_letter')
     instance.save()
     return Response({
         "id": instance.id,
         "name": instance.name,
         "logo": instance.logo.url,
         "first_letter": instance.first_letter
     },
         status=HTTP_201_CREATED
     )
示例#18
0
class Fdfs():
    def __init__(self, client_file):
        self.client = Fdfs_client(client_file)

    def upload(self, upload_file):
        try:
            ret_upload = self.client.upload_by_filename(upload_file)
            file_id = ret_upload['Remote file_id'].replace('\\', '/')
            return file_id

        except Exception as e:
            return None

    def uploadbyBuffer(self, file, suffix):
        try:
            ret_upload = self.client.upload_by_buffer(file, suffix)
            file_id = ret_upload['Remote file_id'].replace('\\', '/')
            return file_id
        except Exception as e:
            print(e)
            return None

    def downloadbyBuffer(self, file_id):
        try:
            ret_download = self.client.download_to_buffer(file_id)
            ret_content = ret_download['Content']
            return ret_content
        except Exception as e:
            return None

    def download(self, download_file, file_id):
        try:
            ret_download = self.client.download_to_file(download_file, file_id)
            ret_content = ret_download['Content']
            return ret_content
        except Exception as e:
            return None

    def delete(self, file_id):
        try:
            ret_delete = self.client.delete_file(file_id)
            return ret_delete
        except Exception as e:
            return None
示例#19
0
 def update(self, request, *args, **kwargs):
     # 获取修改的对象
     instance = self.get_object()
     # 接收 sku_id
     sku_id = request.data.get('sku')
     # 接收图片数据
     image_file = request.data.get('image')
     # 校验参数
     if not sku_id:
         raise serializers.ValidationError('数据不完整')
     try:
         sku = SKU.objects.get(id=sku_id)
     except:
         raise serializers.ValidationError('修改的商品不存在')
     # 获取修改对象的image_url
     image_url_instance = instance.image.name
     client = Fdfs_client(settings.FDFS_CLIENT_CONF)
     # 删除旧的image, 将其放在事务中执行
     # client.delete_file(image_url_instance)
     # 上传新的图片
     ret = client.upload_appender_by_buffer(image_file.read())
     if ret.get('Status') != 'Upload successed.':
         return Response('图片上传失败')
     # 获取新的url
     image_url = ret.get('Remote file_id')
     with transaction.atomic():
         save_point = transaction.savepoint()
         try:
             # 判断是否修改商品
             if instance.sku_id == int(sku_id):
                 # 只是修改了图片
                 # 判断修改的是否是商品的默认图片, 如果是就要修改sku表
                 if sku.default_image == image_url_instance:
                     sku.default_image = image_url
                     sku.save()
             else:
                 # 商品及图片都修改
                 # 获取被修改的sku
                 sku_old = SKU.objects.get(id=instance.sku_id)
                 # 判断修改的图片是不是被修改商品的默认图片
                 if sku_old.default_image == image_url_instance:
                     # 判断 sku_old 是否还有图片, 要先排除要被修改的图片
                     images = sku_old.images.exclude(
                         image=image_url_instance)
                     if images:
                         # 有就将查询集中的第一张图片设置为默认图片
                         sku_old.default_image = images[0].image
                     else:
                         # 没有就设置为空
                         sku_old.default_image = None
                     sku_old.save()
                 # 判断要修改的商品有没有默认图片, 及有没有图片
                 if not sku.default_image or not sku.images.count():
                     # 如果没有, 就将其设置为默认图片
                     sku.default_image = image_url
                     sku.save()
             # 修改图片表
             instance.image = image_url
             instance.sku_id = sku_id
             instance.save()
         except:
             transaction.savepoint_rollback(save_point)
             raise serializers.ValidationError('修改失败')
         else:
             client.delete_file(image_url_instance)
             transaction.savepoint_commit(save_point)
             serializer = self.get_serializer(instance)
             return Response(serializer.data)
示例#20
0
class FDFSStorage(Storage):
    """
    自定义文件图片储存系统为FDFS,
    仅针对django的后台管理,前端上传要重新写,原理还是这个
    """
    def __init__(self):
        """
        初始化参数
        :param settings.BASE_URL: 图片储存的基类路径
        :param settings.FDFS_CLIENT_CONF:客户端的配置文件的路径
        """
        self.base_url = settings.BASE_URL
        self.client = Fdfs_client(settings.FDFS_CLIENT_CONF)

    def _open(self, name, mode):
        # 前端传过来的已经是二进制文件了,因此可以直接pass不写
        pass

    def _save(self, name, content):
        """重写_save方法为FDFS上传

        upload_by_buffer方法 ->upload_by_buffer(self, filebuffer, file_ext_name=None, meta_dict=None):
        通过file_ext_name设置文件后缀名,(meta_dict设置其他参数信息[猜测可以])
        @meta_dict: dictionary e.g.:{
            'ext_name'  : 'jpg',
            'file_size' : '10240B',
            'width'     : '160px',
            'hight'     : '80px'
            }
        """
        file_type = name.split('.')[-1] if '.' in name else None
        # 传个两次,不成功就算了
        for i in range(2):
            # 调用连接对象的二进制上传文件方法
            result = self.client.upload_by_buffer(content.read(), file_type)
            # 判断上传图片是否成功,失败主动报错
            if result['Status'] == 'Upload successed.':
                break
        else:
            raise Exception('fdfs客户端连接对象上传图片失败')
        # 成功则返回文件id
        self.result = result
        return self.result['Remote file_id']

    def url(self, name):
        """返回图片的fdfs完整路径"""
        return self.base_url + name

    def exists(self, name):
        """让django认为每次上传的文件都是新文件"""
        return False

    def size(self, name):
        """返回图片大小"""
        return self.result.get('Uploaded size')

    def delete(self, name):
        """删除文件, 这个name,就是image字段存在数据库里的值"""
        assert name, "The name argument is not allowed to be empty."
        self.client.delete_file(name)

    def listdir(self, path):
        pass

    def path(self, name):
        return self.url(name)

    def get_accessed_time(self, name):
        return time.time()

    def get_created_time(self, name):
        return time.time()

    def get_modified_time(self, name):
        return time.time()
示例#21
0
class FastDfsStorage(Storage):
    """操作文件通过file_id"""

    def __init__(self, base_url=None, client_conf=None):
        """
        初始化
        :param base_url:构造图片上传的基本url,包括域名,已经搭配nginx
        :param client_conf:FastDfs客户端的配置字典
        """
        if base_url is None:
            base_url = FDFS_URL
        self.base_url = base_url
        if client_conf is None:
            client_conf = FDFS_CLIENT_CONF
        self.client_conf = client_conf
        self.client = Fdfs_client(get_tracker_conf(self.client_conf))

    def _open(self, name, mode='rb'):
        """返回封装后的文件对象"""
        return File(open(self.path(name), mode))

    def open(self, name, mode='rb'):
        """
        从FastDfs中取出文件
        :param name: 文件名
        :param mode: 打开的模式
        :return:
        """
        return self._open(name, mode)

    def _save(self, name, content):
        """
        存储文件到FastDfs上
        :param name:  文件名(无卵用)
        :param content: 打开的file对象
        :return:
        """
        filebuffer = content.read()  # 读取二进制内容
        is_save, ret_upload = self.upload(filebuffer)
        return ret_upload.get('Remote file_id').decode() if is_save else None

    def save(self, name, content, max_length=None):
        """
        Save new content to the file specified by name. The content should be
        a proper File object or any Python file-like object, ready to be read
        from the beginning.
        """
        # Get the proper name for the file, as it will actually be saved.
        # 要不要name无所谓,只是为了尽量不改底层源码
        if name is None:
            name = content.name

        if not hasattr(content, 'chunks'):
            content = File(content, name)

        name = self.get_available_name(name, max_length=max_length)  # 截取固定大小的文件名长度
        return self._save(name, content)


    def update(self, filebuffer, remote_file_id):
        """
        修改文件内容
        :param local_path: 本地文件名
        :param remote_file_id:  fastdfs中的file_id
        @return: dictionary {
            'Status'     : 'Modify successed.',
            'Storage IP' : storage_ip
        }
        """

        try:
            remote_file_id = bytes(remote_file_id.encode("utf-8"))  # 旧的file_id
            ret_update = self.client.modify_by_buffer(filebuffer, remote_file_id)
            if ret_update.get("Status") != 'Modify successed.':
                raise Exception
            return True, ret_update
        except Exception as e:
            common_logger.info(e)
            return None, "文件更新失败"

    def upload(self, filebuffer, meta_dict=None):
        """
        保存文件时回调的函数
        保存在FastDfs中
        通过client来操作
        :param name: 文件名
        :param filebuffer: 文件内容(二进制)
        :param meta_dict: dictionary e.g.:{
            'ext_name'  : 'jpg',
            'file_size' : '10240B',
            'width'     : '160px',
            'hight'     : '80px'
        }
        @return dict {
            'Group name'      : group_name,
            'Remote file_id'  : remote_file_id,
            'Status'          : 'Upload successed.',
            'Local file name' : '',
            'Uploaded size'   : upload_size,
            'Storage IP'      : storage_ip
        } if success else None
        """
        try:
            ret_upload = self.client.upload_by_buffer(filebuffer)
            if ret_upload.get("Status") != "Upload successed.":
                raise Exception
            return True, ret_upload
            # file_name为bytes类型,只能返回str类型,不然会报错
        except Exception as e:
            return False, None

    def url(self, name):
        """
        返回文件的完整URL路径给前端
        :param name: 数据库中保存的文件名
        :return: 完整的URL
        """
        return self.base_url + '/' + name

    def exists(self, name):
        """
        判断文件是否存在,FastDFS可以自行解决文件的重名问题
        所以此处返回False,告诉Django上传的都是新文件
        :param name:  文件名
        :return: False
        """
        return False

    def download_to_file(self, local_path, remote_file_id):
        """
        从FastDfs分布式文件系统进行下载文件,保存成文件格式
        :param local_path: 本地保存文件路径
        :param remote_file_id: 上传到FastDfs文件系统中自动生成的文件路径即文件id,
        :return True/False, dict {
            'Remote file_id'  : remote_file_id,
            'Content'         : local_filename,
            'Download size'   : downloaded_size,
            'Storage IP'      : storage_ip
        }
        """
        try:
            ret_download = self.client.download_to_file(local_path, remote_file_id)
            return True, ret_download
        except Exception as e:
            return False, None

    def download_to_buffer(self, remote_file_id, offset=0, down_bytes=0):
        """
        通过文件名从FastDfs上下载文件,存储为buffer格式
        :param local_filename: 本地文件名,一般存于数据库
        :param remote_file_id: 远程文件id
        :param offset: 文件数据起始偏移量
        :param down_bytes: 需要下载的文件大小
        :return:return True/False, dict {
            'Remote file_id'  : remote_file_id,
            'Content'         : file_buffer,
            'Download size'   : downloaded_size,
            'Storage IP'      : storage_ip
        }
        """
        try:
            ret_download = self.client.download_to_buffer(remote_file_id, offset, down_bytes)
            return True, ret_download
        except Exception as e:
            return False, None


    def modify_by_buffer(self, filebuffer, appender_fileid, offset=0):
        """
        通过buffer修改文件内容
        :param filebuffer:文件buffer
        :param appender_fileid:远程文件id
        :param offset:起始偏移量
        :return:True/False, dictionary {
            'Status'     : 'Modify successed.',
            'Storage IP' : storage_ip
        }
        """

        try:
            ret_modify = self.client.modify_by_buffer(filebuffer, appender_fileid, offset)
            return True, ret_modify
        except Exception as e:
            return False, None

    def delete(self, remote_file_id):
        """
        从FastDfs分布式文件系统中将文件删除
        :param remote_file_id: 上传到FastDfs文件系统中自动生成的文件路径即文件id
        @return True/False, tuple ('Delete file successed.', remote_file_id, storage_ip)
        """
        try:
            ret_delete = self.client.delete_file(remote_file_id)
            return True, ret_delete
        except Exception as e:
            return False, None
示例#22
0
client = Fdfs_client('client.conf')

# 上传文件
# ret = client.upload_by_filename('/home/python/Desktop/iphone.jpg')
"""
{
    'Group name': 'group1',
    'Storage IP': '192.168.136.130',
    'Local file name': '/home/python/Desktop/iphone.jpg',
    'Status': 'Upload successed.',
    'Uploaded size': '6.00KB',
    'Remote file_id': 'group1/M00/00/02/wKiIgl09S5SAM9cSAAAaSQ5Z0Cc893.jpg'
}
"""
# 修改文件
# ret = client.modify_by_file('/home/python/Desktop/huawei.jpg', 'group1/M00/00/02/wKiIgl09S5SAM9cSAAAaSQ5Z0Cc893.jpg')
"""
包错误
使用先删除在上传的方法
"""

# 删除
ret = client.delete_file('group1/M00/00/02/wKiIgl09S5SAM9cSAAAaSQ5Z0Cc893.jpg')
"""
(
    'Delete file successed.',
    'group1/M00/00/02/wKiIgl09S5SAM9cSAAAaSQ5Z0Cc893.jpg', '192.168.136.130'
)
"""
print(ret)
示例#23
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 3/7/19 9:39 AM
# @Author  : Lijunjie
# @Site    :
# @File    : upload_file
# @Software: PyCharm

import os
from fdfs_client.client import Fdfs_client

dirname = "/mnt/hgfs/CS/培训/14天天生鲜项目/dailyfresh/static/images"
client = Fdfs_client("/etc/fdfs/client.conf")

for main_dir, subdir, file_name_list in os.walk(dirname):
    for file_name in file_name_list:
        file = os.path.join(main_dir, file_name)
        with open(file, 'rb') as f_obj:
            res = client.upload_by_buffer(f_obj.read())
        print(file)
        print(res["Remote file_id"])
        client.delete_file(res['Remote file_id'])