None

Logging Binary File Downloads in Django

December 17, 2009

I had a need to download binary files from a Django website and to log the fact that they had been downloaded, including which logged in user did the download.

This example also shows the usage of the content-disposition header to set the default filename of the downloaded file. This comes from a display_name field specified during the fileupload.

class MyFile(file):
    def __init__(self, pDownloadFile, pUser, *args, **kwargs):
       self.downloadFile = pDownloadFile
       self.user = pUser
       lFilename = self.downloadFile.file.name
       print lFilename
       super(MyFile, self).__init__(lFilename, *args, **kwargs)

    def close(self):
       super(MyFile, self).close()
       lDownloadLog = DownloadLog()
       lDownloadLog.filename = self.downloadFile.file.name
       lDownloadLog.lastChangedBy = self.user
       lDownloadLog.owner = self.user
       lDownloadLog.save()

@login_required
def downloads_list(request):
    """
    Show list of files to download
    """
    lReleases = Release.objects.all()
    return render_auth(request, 'downloads/filelist.html', {"Releases" : lReleases})

@login_required
def download_file(request, pReleaseId, pDownloadFileId):
    """
    Download file to browser
    """
    try:
        lRelease = Release.objects.filter(id=pReleaseId)[0]
        lDownloadFile = DownloadFile.objects.filter(id=pDownloadFileId)[0]
    except IndexError:
        raise Http404()
    lFile = MyFile(lDownloadFile, request.user)
    lResponse = HttpResponse(lFile, mimetype='application/octet-stream')
    lResponse['Content-Disposition'] = 'attachment; filename=%s' % lDownloadFile.display_name
    return lResponse