Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django:如何允许可疑文件操作/复制文件_Python_Django - Fatal编程技术网

Python Django:如何允许可疑文件操作/复制文件

Python Django:如何允许可疑文件操作/复制文件,python,django,Python,Django,我想执行django默认不允许的可疑文件操作 我正在编写一个命令(通过manage.py importfiles运行),以便在Django中我自己编写的文件存储中导入真实文件系统上的给定目录结构 我想,这是我的相关代码: def _handle_directory(self, directory_path, directory): for root, subFolders, files in os.walk(directory_path): for filename in

我想执行django默认不允许的
可疑文件操作

我正在编写一个命令(通过
manage.py importfiles
运行),以便在Django中我自己编写的文件存储中导入真实文件系统上的给定目录结构

我想,这是我的相关代码:

def _handle_directory(self, directory_path, directory):
    for root, subFolders, files in os.walk(directory_path):
        for filename in files:
            self.cnt_files += 1
            new_file = File(directory=directory, filename=filename, file=os.path.join(root, filename),
                 uploader=self.uploader)
            new_file.save()
回溯是:

Traceback (most recent call last):
  File ".\manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 399, in execute_from_command_line
    utility.execute()
  File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Python27\lib\site-packages\django\core\management\base.py", line 242, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "C:\Python27\lib\site-packages\django\core\management\base.py", line 285, in execute
    output = self.handle(*args, **options)
  File "D:\Development\github\Palco\engine\filestorage\management\commands\importfiles.py", line 53, in handle
    self._handle_directory(args[0], root)
  File "D:\Development\github\Palco\engine\filestorage\management\commands\importfiles.py", line 63, in _handle_directory
    new_file.save()
  File "D:\Development\github\Palco\engine\filestorage\models.py", line 157, in save
    self.sha512 = hashlib.sha512(self.file.read()).hexdigest()
  File "C:\Python27\lib\site-packages\django\core\files\utils.py", line 16, in <lambda>
    read = property(lambda self: self.file.read)
  File "C:\Python27\lib\site-packages\django\db\models\fields\files.py", line 46, in _get_file
    self._file = self.storage.open(self.name, 'rb')
  File "C:\Python27\lib\site-packages\django\core\files\storage.py", line 33, in open
    return self._open(name, mode)
  File "C:\Python27\lib\site-packages\django\core\files\storage.py", line 160, in _open
    return File(open(self.path(name), mode))
  File "C:\Python27\lib\site-packages\django\core\files\storage.py", line 261, in path
    raise SuspiciousFileOperation("Attempted access to '%s' denied." % name)
django.core.exceptions.SuspiciousFileOperation: Attempted access to 'D:\Temp\importme\readme.html' denied.
回溯(最近一次呼叫最后一次):
文件“\manage.py”,第10行,在
从命令行(sys.argv)执行命令
文件“C:\Python27\lib\site packages\django\core\management\\ uuuu init\uuuu.py”,第399行,从命令行执行
utility.execute()
文件“C:\Python27\lib\site packages\django\core\management\\uuuu init\uuuuu.py”,第392行,在execute中
self.fetch_命令(子命令)。从_argv(self.argv)运行_
文件“C:\Python27\lib\site packages\django\core\management\base.py”,第242行,运行于\u argv
self.execute(*args,**选项._dict__;
文件“C:\Python27\lib\site packages\django\core\management\base.py”,第285行,在execute中
输出=self.handle(*args,**选项)
文件“D:\Development\github\Palco\engine\filestorage\management\commands\importfiles.py”,第53行,位于句柄中
self.\u handle\u目录(args[0],根目录)
文件“D:\Development\github\Palco\engine\filestorage\management\commands\importfiles.py”,第63行,在\u handle\u目录中
新建_文件。保存()
文件“D:\Development\github\Palco\engine\filestorage\models.py”,第157行,保存
self.sha512=hashlib.sha512(self.file.read()).hexdigest()
文件“C:\Python27\lib\site packages\django\core\files\utils.py”,第16行,在
read=属性(lambda self:self.file.read)
文件“C:\Python27\lib\site packages\django\db\models\fields\files.py”,第46行,在get文件中
self.\u file=self.storage.open(self.name,'rb')
文件“C:\Python27\lib\site packages\django\core\files\storage.py”,第33行,打开
返回自身。\u打开(名称、模式)
文件“C:\Python27\lib\site packages\django\core\files\storage.py”,第160行,打开
返回文件(打开(self.path(名称),模式))
文件“C:\Python27\lib\site packages\django\core\files\storage.py”,第261行,路径
引发可疑文件操作(“拒绝尝试访问“%s”。%name)
django.core.exceptions.Su疑文件操作:尝试访问“D:\Temp\importme\readme.html”被拒绝。
这个。这个

如果不想检查模型:my
file
类的属性
file
是一个


我假设,这个问题发生了,因为我只是“链接”到找到的文件。但我需要复制它,嗯?如何将文件复制到文件中?

检查文件路径前是否有斜杠

file_item = models.FileField(upload_to=content_file_name)


def content_file_name(username, filename):
    return '/'.join(['content', username, filename])

注意这里的
“content”
不是
“/content”
。这就是我的问题。

分析stacktrace的这一部分:

File "C:\Python27\lib\site-packages\django\core\files\storage.py", line 261, in path
    raise SuspiciousFileOperation("Attempted access to '%s' denied." % name)
导致标准Django
文件系统存储
。它希望文件位于您的
媒体根目录中。您的文件可以位于文件系统中的任何位置,因此会出现此问题

您应该传递类似文件的对象,而不是
文件
模型的路径。实现这一点的最简单方法是使用Django
File
class,它是python类文件对象的包装器。有关更多详细信息,请参阅

更新:

好的,我在这里建议一个从文档中选取的路线:

from django.core.files import File as FileWrapper

def _handle_directory(self, directory_path, directory):
    for root, subFolders, files in os.walk(directory_path):
        for filename in files:
            self.cnt_files += 1
            new_file = File(
                 directory=directory, filename=filename,
                 file=os.path.join(root, filename),
                 uploader=self.uploader)
            with open(os.path.join(root, filename), 'r') as f:
                file_wrapper = FileWrapper(f)
                new_file = File(
                    directory=directory, filename=filename,
                    file=file_wrapper,
                    uploader=self.uploader)
                new_file.save()

如果有效,应将文件复制到您的
安全存储提供的位置。

在Django中,通过从外部目录读取文件并在项目介质中创建一个tmp文件,然后将其保存在适当的文件文件中,可以避免可疑的文件操作,如下所示

import tempfile

file_name="file_name.pdf"
EXT_FILE_PATH = "/home/somepath/"
file_path = EXT_FILE_PATH + file_name
if exists(file_path):
    #create a named temporary file within the project base , here in media

    lf = tempfile.NamedTemporaryFile(dir='media')
    f = open(file_path, 'rb')
    lf.write(f.read())
    #doc object with file FileField.

    doc.file.save(file_name, File(lf), save=True)
    lf.close()

我没有遇到过类似的问题,但有相关的问题。我最近将Django 1.8升级到1.11

现在,如果尝试在具有FileField的模型中保存文件,则会出现以下错误:

可疑文件操作位于/api/send\u report/ 连接的路径(/vagrant/tmp/test_file.pdf)位于基本路径组件(/vagrant/media)的外部

我要保存文件的模型:

class Report(BaseModel):
    file = models.FileField(max_length=200, upload_to=os.path.join(settings.REPORTS_URL, '%Y/week_%W/'))
    type = models.CharField(max_length=20, verbose_name='Type', blank=False, default='', db_index=True)
我正在尝试使用以下代码从不在MEDIA_根目录中的tmp文件夹保存文件:

from django.core.files import File

filepath = "/vagrant/tmp/test_file.pdf"
file = File(open(filepath, "rb"))
report_type = "My_report_type"
report = Report.objects.create(
    file=file,
    type=report_type,
)
我为解决问题所做的工作:

import os
from django.core.files import File

filepath = "/vagrant/tmp/test_file.pdf"
file = File(open(filepath, "rb"))
file_name = os.path.basename(file.name)
report_type = "My_report_type"
report = Report.objects.create(
    type=report_type,
)
report.file.save(file_name, file, save=True)

希望它能帮助别人。

在Django,什么地方会引起问题?你只在代码中包含了一部分,我很确定你自己不会引起怀疑:)?我在我的问题中添加了完整的后台程序。我创建了一个后续问题:不,这不是解决方案:(我在读取要导入的文件时遇到问题。@tjati-当文件路径前面有一个“/”时,我遇到了类似的错误,我通过删除该“/”来修复它(
/
),我想这会对你有帮助…好的,我理解第一段。但是我不知道如何调用Django的
文件
模型以及复制操作是如何工作的。更新了,包含了关于这一部分的更多细节。让我知道这是否有帮助。好吧,非常感谢!这很有帮助,而且复制文件确实有效!不过,我有一个新的问题lem:(这是一个例外:
django.db.utils.ProgrammingError:您不能使用8位ByTestRing,除非您使用可以解释8位ByTestRing的文本工厂(如text\u factory=str)。强烈建议您只需将应用程序切换到Unicode字符串。
-我更新了我的问题,如果您可以研究的话,我会通知您。很高兴它成功了!这是一个非常独立的问题,您应该发布关于它的新问题。您能提供失败的SQL吗?谢谢。您是对的,这是一个新问题在发布后,我也有同样的想法。因此,我回复了这个问题的上一次更新,并将您的答案标记为正确,因为它是正确的。我重新发布了我的新问题:-也许您会查看它。