Django: How to allow a Suspicious File Operation / copy a file

后端 未结 4 555
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-04 01:54

I want to do a SuspiciousFileOperation which django disallows by default.

I am writing a command (to run via manage.py importfiles) to impo

相关标签:
4条回答
  • 2020-12-04 02:38

    Check if there is slash before your filepath

    file_item = models.FileField(upload_to=content_file_name)
    
    
    def content_file_name(username, filename):
        return '/'.join(['content', username, filename])
    

    Note here "content" not "/content". That was the problem for me.

    0 讨论(0)
  • 2020-12-04 02:44

    Analyzing this part of stacktrace:

    File "C:\Python27\lib\site-packages\django\core\files\storage.py", line 261, in path
        raise SuspiciousFileOperation("Attempted access to '%s' denied." % name)
    

    leads to the standard Django FileSystemStorage. It expects files to be within your MEDIA_ROOT. Your files can be anywhere in the file system, therefore this problem occurs.

    You should pass file-like object instead of a path to your File model. The easiest way to achieve that would be to use Django File class, which is a wrapper around python file-like objects. See File object documentation for more details.

    Update:

    Ok, I am suggesting here a route taken from the docs:

    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()
    

    If it works it should copy the file to the location provided by your secure_storage callable.

    0 讨论(0)
  • 2020-12-04 02:44

    I haven't faced similar problem but related issue. I have recently upgraded Django 1.8 to 1.11.

    Now I am getting the following error if try to save a file in a model having FileField field:

    SuspiciousFileOperation at /api/send_report/ The joined path (/vagrant/tmp/test_file.pdf) is located outside of the base path component (/vagrant/media)

    My model where I want to save the file:

    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)
    

    I am trying following codes to save the file from tmp folder which is not located in MEDIA_ROOT:

    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,
    )
    

    What I have done to solve the issue:

    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)
    

    Hope it will help someone.

    0 讨论(0)
  • 2020-12-04 02:55

    In Django, SuspiciousFileOperation can be avoid by read the file from external dir and make a tmp file within the project media then save in the appropriate file filed as below

    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()
    
    0 讨论(0)
提交回复
热议问题