2010-03-29 10 views
13

Ich möchte einige Dateien in einer HttpResponse zurückgeben und ich verwende die folgende Funktion. Die Datei, die zurückgegeben wird, hat immer eine Dateigröße von 1 KB und ich weiß nicht warum. Ich kann die Datei öffnen, aber es scheint, dass sie nicht korrekt bedient wird. Also wollte ich wissen, wie man Dateien mit django/python über eine HttpResponse zurückgeben kann.django Rückgabedatei über HttpResponse - Datei wird nicht korrekt bedient

@login_required 
def serve_upload_files(request, file_url): 
    import os.path 
    import mimetypes 
    mimetypes.init() 

    try: 
     file_path = settings.UPLOAD_LOCATION + '/' + file_url 
     fsock = open(file_path,"r") 
     #file = fsock.read() 
     #fsock = open(file_path,"r").read() 
     file_name = os.path.basename(file_path) 
     file_size = os.path.getsize(file_path) 
     print "file size is: " + str(file_size) 
     mime_type_guess = mimetypes.guess_type(file_name) 
     if mime_type_guess is not None: 
      response = HttpResponse(fsock, mimetype=mime_type_guess[0]) 
     response['Content-Disposition'] = 'attachment; filename=' + file_name    
    except IOError: 
     response = HttpResponseNotFound() 
    return response 

Edit: Der Fehler ist eigentlich kein Fehler ;-)

Diese Lösung wird in der Produktion auf einem Apache-Server arbeiten, so ist die Quelle ok.

Beim Schreiben dieser Frage habe ich es lokal mit dem Django-Entwicklungsserver getestet und habe mich gefragt, warum es nicht funktioniert. Ein Freund von mir sagte mir, dass dieses Problem auftreten könnte, wenn die MIME-Typen nicht im Server eingestellt sind. Aber er war sich nicht sicher, ob das das Problem ist. Aber eins ist sicher .. es hat etwas mit dem Server zu tun.

+8

Für diejenigen, die versuchen, diesen Code zu verwenden, bedenken Sie, dass das Argument 'mimetype' in der' HttpResponse' durch das Feld 'content_type' ersetzt wurde. –

Antwort

9

Versuchen Sie, den fsock Iterator als Parameter zu HttpResponse() statt zu seiner write() Methode, die ich denke, erwartet eine Zeichenfolge übergeben.

response = HttpResponse(fsock, mimetype=...) 

Siehe http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators

Auch ich bin nicht sicher, dass Sie close auf Ihre Datei aufrufen möchten, bevor response zurückkehren. Nachdem ich in der Shell damit herumgespielt habe (ich habe das in einer tatsächlichen Django-Ansicht nicht versucht), scheint es, dass die response nicht auf die Datei zugreift, bis die response selbst gelesen wird. Der Versuch, eine HttpResponse zu lesen, die mit einer Datei erstellt wurde, die jetzt geschlossen ist, führt zu ValueError: I/O operation on closed file.

So können Sie fsock geöffnet lassen, und lassen Sie den Garbage Collector damit umgehen, nachdem die Antwort gelesen wird.

+0

Hallo, danke für deine Antwort. Leider ändert sich daran nichts. Antwort = HttpResponse (fsock, mimetype = mime_type_guess [0]). Die Datei wird immer noch nicht korrekt geliefert. Zusätzlich überprüfte ich die Dateigröße (mit file_size = os.path.getsize (Dateipfad) print "Dateigröße ist:" + str (file_size)), bevor ich es über die HttpResponse zurückgebe und es zurückgibt: Dateigröße ist: 56349. Daher wird die Datei korrekt aus dem Dateisystem gelesen, und bei der Rückgabe ist ein Fehler aufgetreten. –

+0

Tom Tom, siehe Ergänzungen zu meiner Antwort. –

+0

Ich stimme mit Ben überein. Wenn fsock zur HttpResponse hinzugefügt wird, entweder im Konstruktor oder mit der Methode 'write', wird es dem internen Inhaltstapel hinzugefügt, den HttpResponse verwaltet. Dieser Stapel wird erst zu einem späteren Zeitpunkt ausgewertet, zu dem Zeitpunkt, zu dem die Antwort tatsächlich benötigt wird.Sie müssen den fsock offen lassen oder sonst HttpResponse wird einen Fehler auslösen, wenn versucht wird, davon zu lesen. Der Garbage Collector kümmert sich um das Schließen der Datei. –

11

Könnte es sein, dass die Datei einige nicht-ASCII-Zeichen enthält, die in der Produktion, aber nicht in der Entwicklung in Ordnung sind?

Versuchen Sie die Datei als Binär-Lesen:

fsock = open(file_path,"rb") 
+3

Du bist mein Retter Alle Hauptbeiträge für das Versenden von Dateien über Django decken diese binäre Notwendigkeit nicht ab, wenn sie von Windows geliefert werden. Übrigens funktioniert die Einstellung "rb" während der Verwendung von FileWrapper um Chunks zu versorgen via: return HttpResponse (FileWrapper (offen (Dateiname, "rb")), content_type = mimetypes.guess_type (Dateiname) [0]) – garromark

1

Try "django.middleware.gzip.GZipMiddleware" von Ihrem MIDDLEWARE_CLASSES in settings.py deaktivieren

ich hatte das gleiche Problem, und nachdem ich sah um den Middleware-Ordner herum schien mir diese Middleware schuldig zu sein und das Entfernen hatte den Zweck für mich.

Verwandte Themen