Django无法打开下载的zip文件[重复]

dauxcl2d  于 2023-10-21  发布在  Go
关注(0)|答案(1)|浏览(107)

此问题已在此处有答案

How to send file to response in Django?(3个答案)
2天前关闭。
我想通过点击一个按钮下载一个包含所有附件的笔记到Django的zip文件中。
这就是观点:

  1. def download_note(request, pk):
  2. note = get_object_or_404(Note, pk=pk)
  3. file_path = f'notes/media/downloaded_notes/note{note.id}.txt'
  4. notefiles = NoteFile.objects.filter(note=note)
  5. urls = [f.file.url for f in notefiles]
  6. if get_language() == 'en':
  7. content = f'Title: {note.title}, Author: {note.user}, Date: {note.add_date.strftime("%d-%m-%Y %H:%M:%S")}\n' \
  8. f'Category: {note.category}\n' \
  9. f'Note:\n{note.note_text}'
  10. else:
  11. content = f'Tytuł: {note.title}, Autor: {note.user}, Data: {note.add_date.strftime("%d-%m-%Y %H:%M:%S")}\n' \
  12. f'Kategoria: {note.category}\n' \
  13. f'Notatka:\n{note.note_text}'
  14. with open(file_path, 'w', encoding='utf-8') as f:
  15. f.write(content)
  16. zip_file_path = f'notes/media/downloaded_notes/note{note.id}.zip'
  17. with zipfile.ZipFile(zip_file_path, 'w') as zipf:
  18. zipf.write(file_path, os.path.basename(file_path))
  19. media_root = settings.MEDIA_ROOT.replace('\\', '/')
  20. print(media_root)
  21. for url in urls:
  22. print(f'{media_root}{url[6:]}')
  23. #file_url = os.path.join(media_root, url[6:])
  24. #zipf.write(file_url, os.path.basename(url[6:]))
  25. file_name = os.path.basename(url)
  26. zipf.write(f'{media_root}{url[6:]}', file_name)
  27. with open(zip_file_path, 'rb') as f:
  28. response = FileResponse(f.read(), content_type='application/zip')
  29. response['Content-Disposition'] = f'attachment; filename="note{note.id}.zip"'
  30. return response

当我点击下载按钮Chrome挂起几秒钟,然后文件下载。但是下载目录中的zip文件不起作用。当我试图打开它有一个消息说,该文件的格式无效或文件已损坏。但是当我进入django project和media/downloaded_notes/note70.zip时,一切都很好。
所以我认为这个片段有一个问题:

  1. with open(zip_file_path, 'rb') as f:
  2. response = FileResponse(f.read(), content_type='application/zip')
  3. response['Content-Disposition'] = f'attachment; filename="note{note.id}.zip"'

这段代码有什么问题?

x0fgdtte

x0fgdtte1#

请使用HttpResponse代替FileResponse

  1. from django.http import HttpResponse
  2. with open(zip_file_path, 'rb') as f:
  3. response = HttpResponse(f.read(), content_type='application/zip')
  4. response['Content-Disposition'] = f'attachment; filename="note{note.id}.zip"'
  5. # You can also set the content length if you know it:
  6. # response['Content-Length'] = os.path.getsize(zip_file_path)
  7. return response

相关问题