Reputation: 563
i have an app in django that do some processes and build a file, in one section, i want to show the user that file to download that.
(for example, user enter a name in front-end and the app give him a pdf file to download).
the file building process is ok and it is in /app_dir/media/app/report/username/file.pdf
here is my code, but it does not worked and i faced some problems.
can you please help me, where is my problem?
and how i can make that user-specefic? each user just can access to his files.
views.py (my_main_function):
@login_required(login_url='/login/')
def my_function(request):
if request.method == 'GET':
return render(request, 'app/my_function.html')
else:
try:
#my main process to build .PDF file
except ValueError:
return render(request, 'app/dashboard.html', {'error':'Bad data passed in. Try again.'})
return render(request, 'app/download.html')
views.py (download function):
def download_file(request):
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
filename = f"{file}.pdf"
# Define the full file path
filepath = f"{BASE_DIR}/app/media/app/reports/{user_name}/{filename}"
# Open the file for reading content
path = open(filepath, 'rb')
path.read()
# Set the return value of the HttpResponse
response = HttpResponse(path, content_type='application/pdf')
# Set the HTTP header for sending to browser
response['Content-Disposition'] = "attachment; filename=%s" % filepath
# Return the response value
return response
urls.py:
path('download/', views.download_file, name='download_file'),
simple testing download.html file:
<html>
<title>Download File</title>
</head>
<body>
<enter>
<h1>Download File using link</h1>
<a href="{% url 'download_file' %}">Download PDF</a>
</center>
</body>
</html>
Upvotes: 0
Views: 836
Reputation: 756
It is not clear what problems you have encountered, but there are some lines I would correct in your code
# first of all why not use django.http.FileResponse instead of HttpResponse?
# https://docs.djangoproject.com/en/3.2/ref/request-response/#fileresponse-objects
from django.http import FileResponse
# if you want files to be accessible only to owners
# you probably should force user to login before download
@login_required
def download_file(request):
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
filename = f"{file}.pdf"
filepath = f"{BASE_DIR}/app/media/app/reports/{user_name}/{filename}"
# somewhere here you need to check if user has access to the file
# if files ownership based solely on {user_name} dir in filesystem
# then it is enough to check if file exists
if os.path.exists(filepath):
response = FileResponse(open(filepath, 'rb'))
# it is probably better to use filename instead of filepath
response['Content-Disposition'] = "attachment; filename=%s" % filename
return response
else:
raise Http404
Upvotes: 1