__init__() got an unexpected keyword argument 'headers' (Django 3.2)

Viewed 2945

In my django web app, I create a .csv file from a list in my views.py and I want the user to be able to download it when the button is pressed. However, when this is run, I get the error that 'headers' is an unexpected argument.

This is the code in my views.py:

output = ['a', 'b', 'c']
response = HttpResponse(content_type='text/csv', headers={'Content-Disposition': 'attachment; filename="myfile.csv"'})
writer = csv.writer(response)
writer.writerows(output)
return response

I have no idea why this doesn't work, since I have used identical code elsewhere with success in the past. Does anyone know if this could be a browser support issue?

2 Answers

Another way to set your header for HttpResponse is like this:

response['Content-Disposition'] = 'attachment; filename="myfile.csv"'

For the error you are getting, can you double check that your django version is indeed 3.2?

I was able to make it work (but not really). I pass the output to the same webpage in a template in JSON format. Then I download the contents of that template using JavaScript. It works, but it feels janky and there are two fairly significant drawbacks to this approach:

  1. All of the form fields on that webpage are reset
  2. Commas in strings become a new cell in the .csv file, shifting everything after to the right.

views.py

output = json.dumps(output)
form = MyForm(initial={'data':my_data})
return render(request, 'wireCalculator/chassis.html', {'base':base, 'download':output, 'form':form})

html page addition:

<div style="display: none;">
    <p id="download">{{ download }}</p>
</div>

Javascript addition:

function download(filename, text) {
    // creates a link, downloads it, then deletes the link
    var element = document.createElement('a')
    element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text))
    element.setAttribute('download', filename)

    element.style.display = 'none'
    document.body.appendChild(element)

    element.click()

    document.body.removeChild(element)
}

const download = JSON.parse(document.getElementById("download").innerHTML)

if (download != "") {
    var downloadText = ""
    for (i=0; i < download.length; i++){
        downloadText = downloadText.concat(download[i])
        downloadText = downloadText.concat("\n")
    }
    download("filename.csv", downloadText)
}
Related