Возможно ли использовать axios/fetch для открытия страницы в новом окне, чтобы загрузить csv из api представления?
У меня есть представление Django, которое загружает большой набор данных из rest api в локальный .csv, используя StreamingHttpResponse. Это отлично работает; однако, когда я пытаюсь добавить аутентификацию с помощью тега [IsAuthenticated] permissions_classes, url (конечно же) становится недоступным без включения в заголовок действительного токена Bearer пользователя.
Вот соответствующий код из файла views.py:
import csv
from django.http import StreamingHttpResponse
class Echo:
def write(self, value):
return value
def streaming_csv_view(request):
queryset = Emissions.objects.all().values_list('year', 'value')
echo_buffer = Echo()
csv_writer = csv.writer(echo_buffer)
labels=[('Year', 'Value')]
rows = (csv_writer.writerow(row) for row in chain(labels,queryset))
response = StreamingHttpResponse(rows, content_type="text/csv")
response["Content-Disposition"] = 'attachment; filename="Emissions.csv"'
return response
Я делаю это в других местах моего кода для более стандартных вызовов API (т.е. для получения данных), но не могу понять, как заставить это работать для загрузки csv, которая требует, чтобы пользователь посетил страницу... Могу ли я использовать вызов fetch/axios для открытия этой страницы в новом окне, чтобы инициировать загрузку, а затем закрыть окно после завершения загрузки? Мне трудно найти примеры использования axios таким образом
Мне кажется, что я что-то упускаю... Любая помощь будет очень признательна.
Вот типичный запрос fetch GET к конечной точке, который не будет работать...
const fetchData = async() => {
url = `link/api/export-emissions`
try{
const response = await fetch(url,{
method:'GET',
headers:{
'Content-Type':'application/json',
'Authorization':'Bearer ' + String(authTokens.access)
}
})
}catch (e){
console.log(e)
}
}
Я предполагаю, что ваш url работает нормально, однако вы можете попробовать этот подход к загрузке csv-файла, используя ваш url и axios.
axios
.get("--your-url---", { // eg.https://picsum.photos/800/800 (no auth required)
responseType: "blob",
headers: {
Authorization: `Bearer YOUR_TOKEN_HERE`, //add your token here
},
onDownloadProgress: function (progressEve) {
console.log(
((progressEve.loaded / progressEve.total) * 100).toFixed() + "%"
);
},
})
.then((object) => {
const url = URL.createObjectURL(object.data);
const anchor = document.createElement("a");
anchor.href = url;
anchor.download = "name_of_file.extension"; //add name and extension
anchor.style.display = "none";
document.body.appendChild(anchor);
anchor.click();
anchor.remove();
URL.revokeObjectURL(url);
})
.catch((error) => console.log(error));