2010-02-16 11 views
8

Me gustaría almacenar los archivos cargados en un directorio específico que depende del URI de la solicitud POST. Tal vez, también me gustaría cambiar el nombre del archivo a algo fijo (el nombre de la entrada del archivo, por ejemplo), así que tengo una manera fácil de grep el sistema de archivos, etc. y también para evitar posibles problemas de seguridad.Django carga el archivo en el directorio específico que depende del POST URI

¿Cuál es la forma preferida de hacer esto en Django?

Editar: Debo aclarar que me interesaría posiblemente hacer esto como un controlador de carga de archivos para evitar escribir dos veces un archivo grande en el sistema de archivos.

Edit2: Supongo que uno puede simplemente 'mv' el archivo tmp a una nueva ubicación. Es una operación barata si está en el mismo sistema de archivos.

+0

moviendo el archivo temporal está bien.Django comprueba este caso y no se queja si se pierde: http://code.djangoproject.com/browser/django/trunk/django/core/files/uploadedfile.py#L57 – olooney

Respuesta

3

Django le da control total sobre dónde (y si) guarda los archivos. Ver: http://docs.djangoproject.com/en/dev/topics/http/file-uploads/

El siguiente ejemplo muestra cómo combinar la URL y el nombre del archivo subido y escribir el archivo al disco:

def upload(request): 
    folder = request.path.replace("/", "_") 
    uploaded_filename = request.FILES['file'].name 

    # create the folder if it doesn't exist. 
    try: 
     os.mkdir(os.path.join(BASE_PATH, folder)) 
    except: 
     pass 

    # save the uploaded file inside that folder. 
    full_filename = os.path.join(BASE_PATH, folder, uploaded_filename) 
    fout = open(full_filename, 'wb+') 
    # Iterate through the chunks. 
    for chunk in fout.chunks(): 
     fout.write(chunk) 
    fout.close() 

Editar: Cómo hacer esto con un FileUploadHandler? Se trazó hacia abajo a través del código y parece que tiene que hacer cuatro cosas para cambiar la finalidad de la TemporaryFileUploadHandler para guardar fuera del FILE_UPLOAD_TEMP_DIR:

  1. extender TemporaryUploadedFile y anular init() para pasar a través de un directorio diferente a NamedTemporaryFile . Puede usar el try mkdir a excepción del pase que mostré arriba.

  2. extienden TemporaryFileUploadHandler y reemplazan new_file() para utilizar la clase anterior.

  3. también extienden init() para aceptar el directorio donde desea que vaya la carpeta.

  4. agregar dinámicamente el controlador de solicitudes, pasando a través de un directorio determinado a partir de la URL:

    request.upload_handlers = [ProgressBarUploadHandler (request.path.replace ('/', '_')]

Aunque no es trivial, es aún más fácil que escribir un controlador desde cero: en particular, no tendrá que escribir una sola línea de lectura en búfer propensa a errores. Los pasos 3 y 4 son necesarios porque no se transfieren FileUploadHandlers información por defecto, creo, por lo que tendrá que decirlo por separado si desea utilizar la URL de alguna manera.

No puedo recomendar escribir un FileUploadHandler personalizado para esto. Realmente está mezclando capas de responsabilidad. En relación con la velocidad de carga de un archivo a través de Internet, hacer una copia de archivo local es insignificante. Y si el archivo es pequeño, Django lo mantendrá en la memoria sin escribirlo en un archivo temporal. Tengo la mala sensación de que conseguirás que todo esto funcione y descubras que ni siquiera puedes medir la diferencia de rendimiento.

+0

Claro, estaba buscando algo eso no es redundante con django.core.files.uploadhandler.TemporaryFileUploadHandler – kmt

+0

Muy bien. Tomaré eso como * la * respuesta. Pensaba en la misma línea, pero, siendo muy nuevo en Django, quería consultar con alguien. Por cierto, ¿de dónde viene ProgressBarUploadHandler? Supongo que copiar y pegar de algún lado? Lo suficientemente justo. Aprecio el esfuerzo de responder a esta pregunta. – kmt

+0

Aunque, en un segundo, realmente quiero más discusión sobre esto. Por ejemplo, ¿deberían usarse las cosas en django/core/files/storage.py? ¿De qué se trata? – kmt

8

fijo olooney ejemplo. Está funcionando ahora

@csrf_exempt 
def upload_video_file(request): 
    folder = 'tmp_dir2/' #request.path.replace("/", "_") 
    uploaded_filename = request.FILES['file'].name 
    BASE_PATH = '/home/' 
    # create the folder if it doesn't exist. 
    try: 
     os.mkdir(os.path.join(BASE_PATH, folder)) 
    except: 
     pass 

    # save the uploaded file inside that folder. 
    full_filename = os.path.join(BASE_PATH, folder, uploaded_filename) 
    fout = open(full_filename, 'wb+') 

    file_content = ContentFile(request.FILES['file'].read()) 

    try: 
     # Iterate through the chunks. 
     for chunk in file_content.chunks(): 
      fout.write(chunk) 
     fout.close() 
     html = "<html><body>SAVED</body></html>" 
     return HttpResponse(html) 
    except: 
     html = "<html><body>NOT SAVED</body></html>" 
     return HttpResponse(html) 
+1

no llego donde el archivo de contenido (request.FILES [' file '] .read()) la función proviene de. –

+0

de django.core.files.base import ContentFile – user2455668

Cuestiones relacionadas