I’m trying to allow users to download a PDF file that I’ve previously uploaded to the MEDIA_ROOT
folder via the admin console. I’ve emulated the answer in this post, however it’s incomplete and I can’t figure out how to fix this. Hoping someone can spot my issue in the code below.
settings.py
# Absolute filesystem path to the directory that will hold user-uploaded files. # Example: "/home/media/media.lawrence.com/media/" MEDIA_ROOT = str(BASE_DIR) + "/media/" # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash if there is a path component (optional in other cases). # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" MEDIA_URL = '/media/' # Absolute path to the directory that holds static files. # Example: "/home/media/media.lawrence.com/static/" STATIC_ROOT = str(BASE_DIR) + "/static/" # URL that handles the static files served from STATIC_ROOT. # Example: "http://media.lawrence.com/static/" STATIC_URL = '/static/'
models.py
from django.db import models # Create your models here. class ResumeModel(models.Model): pdf = models.FileField(upload_to="resume_app/media/resume/") # So this file gets uploaded to root > media > resume_app > media > resume
admin.py
from django.contrib import admin from .models import ResumeModel # Register your models here. admin.site.register(ResumeModel)
views.py
from django.shortcuts import render from .models import ResumeModel # Create your views here. def resume(request): resume = ResumeModel.objects.all() # < Not sure if this part is needed? return render(request, 'resume.html', context={'resume':resume})
template.html
... <a href="{{ resume.pdf.url }}">Click here to download PDF</a> ...
When I hover over this link, the url it’s pointing to is localhost:8083/resume/
, which is the name of the page we’re currently on, so I think the <a href="{{ resume.pdf.url }}">
is not pointing to the correct url of the PDF file I’ve uploaded. The upload DOES work, the file IS in the root > media > resume_app > media > resume
folder. What do I need to make the link work?
UPDATE
Thanks to the help of @tonio below, and apart from my oversight, I changed the line(s):
def resume(request): resume = ResumeModel.objects.all() # < Not sure if this part is needed? return render(request, 'resume.html', context={'resume':resume})
to
def resume(request): resume = ResumeModel.objects.last() return render(request, 'resume.html', context={'resume':resume})
…which is fine for me as I will only have 1 resume in there, and the last entry will be the most recent upload. I then went into that app’s folder, and deleted the __pycache__
and migrations
folders, performed python manage.py makemigrations resume_app
and python manage.py migrate resume_app
, restarted the server, opened app in incognito window and it worked as desired!
Advertisement
Answer
You’re sending all resume objects stored in the database to the template:
resume = ResumeModel.objects.all()
You can send an specific resume identified by their primary key (see this):
def resume(request, resume_id): resume = get_object_or_404(ResumeModel, resume_id) return render(request, 'resume.html', context={'resume':resume})
Anyway, you can test the template sending the first resume in the database:
def resume(request): resume = ResumeModel.objects.first() return render(request, 'resume.html', context={'resume':resume})