10 votes

Téléchargement de répertoire Django pour obtenir les noms des sous-répertoires

Je suis en train d'écrire une application django pour télécharger un répertoire de fichiers avec des formulaires.

Voici le formulaire que j'utilise et qui permet de télécharger un répertoire :

class FileFieldForm(forms.Form):
    file_field = forms.FileField(widget=forms.ClearableFileInput(attrs=
        {'multiple': True, 'webkitdirectory': True, 'directory': True}))

Il s'agit de la charge utile brute du poste :

------WebKitFormBoundaryPbO3HkrKGbBwgD3sd1
Content-Disposition: form-data; name="csrfmiddlewaretoken"

F575Bgl4U9dzgwePPeSW2ISZKk5c3CnRoqFasdasD0Hep6nD0LnAAObXbF92SUa96NbO2
------WebKitFormBoundaryPbO3HkrKGbBwgDsd31
Content-Disposition: form-data; name="file_field";
filename="MainDir/SubDir1/1.jpg"
Content-Type: image/jpeg

------WebKitFormBoundaryPbOasd3HkrKGbBwgD31
Content-Disposition: form-data; name="file_field";
filename="MainDir/SubDir2/2.jpg"
Content-Type: image/jpeg

Il s'agit de la vue permettant de gérer le formulaire :

class FileFieldView(FormView):
    form_class = FileFieldForm
    template_name = 'upload.html'
    success_url = 'upload'

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        files = request.FILES.getlist('file_field')
        if form.is_valid():
            for f in files:
                pprint("Name of file is " + f._get_name() + ' ' + f.field_name, sys.stderr)
                new_file = FileModel(file=f)
                new_file.save()
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

Le problème est que le nom de l'objet fichier dans django est sans nom de sous-répertoire. Je suppose que l'un des middleware qui gère la requête analyse et supprime les noms de sous-répertoires du nom de fichier. Y a-t-il un moyen d'obtenir le nom de fichier original qui contient les noms de répertoires et de sous-répertoires ?

6voto

Gagik Sukiasyan Points 602

Je crois que c'est ainsi que Django est mis en œuvre. Veuillez vous référer à Document sur le gestionnaire de téléchargement de Django .

Il possède ses propres gestionnaires de téléchargement par défaut MemoryFileUploadHandler y TemporaryFileUploadHandler . Tous deux utilisent le logiciel UploadedFile pour gérer les fichiers, et il dispose d'une fonction _set_name qui prend le nom de base du fichier.

Il y a même un commentaire expliquant pourquoi il prend le nom de base :

def _set_name(self, name):
    # Sanitize the file name so that it can't be dangerous.
    if name is not None:
        # Just use the basename of the file -- anything else is dangerous.
        name = os.path.basename(name)

        # File names longer than 255 characters can cause problems on older OSes.
        if len(name) > 255:
            name, ext = os.path.splitext(name)
            ext = ext[:255]
            name = name[:255 - len(ext)] + ext

    self._name = name

Mais je pense que vous pouvez écrire votre propre gestionnaire de téléchargement qui ne prend pas le nom de base et se comporte comme vous le souhaitez. Voici quelques informations sur la façon dont vous pouvez écrire gestionnaire de téléchargement personnalisé .

Vous devez ensuite définir votre gestionnaire dans FILE_UPLOAD_HANDLERS de la mise en place.

2voto

spiky Points 178

En développant la réponse précédente, une façon d'obtenir le chemin complet à partir d'un téléchargement de répertoire est de remplacer les barres obliques ( \ y / ) dans le chemin d'accès au fichier (qui sont supprimés) avec des traits d'union :

class CustomMemoryFileUploadHandler(MemoryFileUploadHandler):
    def new_file(self, *args, **kwargs):
        args = (args[0], args[1].replace('/', '-').replace('\\', '-')) + args[2:]
        super(CustomMemoryFileUploadHandler, self).new_file(*args, **kwargs)

class CustomTemporaryFileUploadHandler(TemporaryFileUploadHandler):
    def new_file(self, *args, **kwargs):
        args = (args[0], args[1].replace('/', '-').replace('\\', '-')) + args[2:]
        super(CustomTemporaryFileUploadHandler, self).new_file(*args, **kwargs)

@csrf_exempt
def my_view(request):
    # replace upload handlers. This depends on FILE_UPLOAD_HANDLERS setting. Below code handles the default in Django 1.10
    request.upload_handlers = [CustomMemoryFileUploadHandler(request), CustomTemporaryFileUploadHandler(request)]
    return _my_view(request)

@csrf_protect
def _my_view(request):
    # if the path of the uploaded file was "test/abc.jpg", here it will be "test-abc.jpg"
    blah = request.FILES[0].name

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X