当需要将上传的文件保存到别的服务器,而又不修改views里的代码,下面可能对你有点用。 Python26\Lib\site-packages\django\core\files\storage.py 这个文件里有一个FileSystemStorage类,类里的函数_save()进行了上传文件的保存。先上代码:
    def _save(self, name, content):
        full_path = self.path(name)
        print full_path,name
        # Create any intermediate directories that do not exist.
        # Note that there is a race between os.path.exists and os.makedirs:
        # if os.makedirs fails with EEXIST, the directory was created
        # concurrently, and we can continue normally. Refs #16082.
        directory = os.path.dirname(full_path)
        if not os.path.exists(directory):
            try:
                os.makedirs(directory)
            except OSError, e:
                if e.errno != errno.EEXIST:
                    raise
        if not os.path.isdir(directory):
            raise IOError("%s exists and is not a directory." % directory)

        # There's a potential race condition between get_available_name and
        # saving the file; it's possible that two threads might return the
        # same name, at which point all sorts of fun happens. So we need to
        # try to create the file, but if it already exists we have to go back
        # to get_available_name() and try again.

        while True:
            try:
                # This file has a file path that we can move.
                if hasattr(content, 'temporary_file_path'):
                    file_move_safe(content.temporary_file_path(), full_path)
                    content.close()

                # This is a normal uploadedfile that we can stream.
                else:
                    # This fun binary flag incantation makes os.open throw an
                    # OSError if the file already exists before we open it.
                    fd = os.open(full_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0))
                    try:
                        locks.lock(fd, locks.LOCK_EX)
                        for chunk in content.chunks():
                            os.write(fd, chunk)
                    finally:
                        locks.unlock(fd)
                        os.close(fd)
            except OSError, e:
                if e.errno == errno.EEXIST:
                    # Ooops, the file exists. We need a new file name.
                    name = self.get_available_name(name)
                    full_path = self.path(name)
                else:
                    raise
            else:
                # OK, the file save worked. Break out of the loop.
                break

        if settings.FILE_UPLOAD_PERMISSIONS is not None:
            os.chmod(full_path, settings.FILE_UPLOAD_PERMISSIONS)

        return name
代码在这个文件的158行,函数传入参数name,第二句的print语句是我自己加上的,name路径就是存入数据库的路径,full_path路径是全路径,所以调用self.path的作用不言而喻了(代码在242行)。这里不需要全路径。 再往下两个if语句9行,功能:去掉文件名(就是文件夹路径),判断是否存在,不存在创建,然后创建不成功报错。这里也需要创建文件夹目录。 再往下的while语句就是存储文件代码了(\(≧▽≦)/激动~)。第一个if语句不明白是什么意思,在前面不知道怎么有这个属性,我也没往前找,不过应该不碍事,解释中介绍说普通上传在else里面。else里面的代码我只懂for循环,那个locks,在同一目录下有locks.py,看到一堆windows接口没兴趣研究,看注释好像是“有两个线程同时对同名文件写文件,会重新获取文件名”涉及到下面的except。这里直接设置保存图片代码。 最后的if语句应该是设置文件夹的权限。 找到这个文件,开始乱找一气,从models里的save开始没找到。后来想起调试了,没有设置错的上传路径,报错“Attempted access to '\a.jpg' denied”。然后根据Traceback,找到了文件。记录下执行顺序: views里的save(),下面省略若干,到了\lib\site-packages\django\db\models\fields\files.py 249行 file.save(file.name, file, save=False), 86行 self.name = self.storage.save(name, content) 然后到了文件\lib\site-packages\django\core\files\storage.py 44行 name = self.get_available_name(name) , 70行 while self.exists(name):, 230行 return os.path.exists(self.path(name)), 没错时,在45行,转到_save函数。

上一篇:
下一篇:

相关文章:

Categories: 博客记录

0 Responses so far.

Leave a Reply