How to show pdf.filename instead of pdf.title

I have a model



class Pdf(models.Model):
    title = models.CharField(max_length=100, null=True, blank=True)
    file = models.FileField(upload_to=course_file_upload_path, validators=[pdf_ext_validator], null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    # relation to Lesson
    lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE, related_name='pdfs', null=True, blank=True)

    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

In the template if we don’t have a title field entered for the pdf, i would like to show filename of the pdf document, like “Pdf-filename-here.pdf”

Thanks!

You can use the name attribute from the FieldFile object, and strip off any path information that may be part of that field.

I tried many things, one of them is this:
{ pdf.file|cut:‘user.id/courses/files/’ }}

Because the data shows
1/courses/files/PDF_DEMO_-_Copy_tLF2P2u.pdf
so i tried to cut that way.

I also tried from the left, but don’t seem to find the correct solution.

Also tried this {{ pdf.FieldFile.name }} but it’s not showing anything.

I tried this but i am get the error that filter doesnt exist.
{{ pdf.file|split(‘/’)[:1] }}

I tried cut and slice but i am missing an argument…basically have no idea :slight_smile:

My inclination is to do this in the view and not the template.

There might be a way to do it in the template by using a with tag to create a variable for the directory and using that with the cut filter, but I’m not sure that would work.

Okay, i am open to all suggestions, can you please tell me more or share an approach example?

I’d need to see the view to offer a concrete example.

Views for pdf documents are really simple:


# PDF DOCUMENTS
@login_required
@user_passes_test(is_admin_or_owner_or_moderator)
def add_pdf(request):
    form = PdfForm()
    if request.method == 'POST':
        form = PdfForm(request.POST, request.FILES)
        if form.is_valid():
            pdf = form.save(commit=False)
            pdf.created_by = request.user
            pdf.save()
            messages.success(request, 'PDF is uploaded')
            return redirect('dashboard:all_lessons')
        #else:
            #messages.error(request, 'Error. File is most likely not approved')
    
    context = {
        'form': form
    }
    
    return render(request, 'courses/pdf/add.html', context)

# edit pdf document
@login_required
@user_passes_test(is_admin_or_owner_or_moderator)
def edit_pdf(request, pk):
    pdf = Pdf.objects.get(id=pk)
    form = PdfForm(instance=pdf)
    if request.method == 'POST':
        form = PdfForm(request.POST, request.FILES, instance=pdf)
        if form.is_valid():
            form.save()
            messages.success(request, 'PDF is updated')
            return redirect('dashboard:dashboard')
    
    context = {
        'pdf': pdf,
        'form': form
    }
    return render(request, 'courses/pdf/edit.html', context)


# delete pdf document
@login_required
@user_passes_test(is_admin_or_owner_or_moderator)
def delete_pdf(request, pk):
    pdf = Pdf.objects.get(id=pk)

    if request.method == 'POST':
        pdf.delete()
        messages.success(request, 'PDF has been deleted')
        return redirect("dashboard:dashboard")
    
    context = {
        'pdf': pdf
    }
    return render(request, 'courses/pdf/delete.html', context)


# all pdf documents
@login_required
@user_passes_test(is_admin_or_owner_or_moderator)
def all_pdfs(request):
    pdfs = Pdf.objects.all()
    context = {
        'pdfs': pdfs
    }
    return render(request, 'courses/pdf/all-pdfs.html', context)

Then in the template i have a loop
{% for pdf in pdfs %} {% endfor %}

Which view is the one where you want to display the name without the path?

def all_pdfs view is that page.

It is basically a page in the admin where i want to show pdf material that the client has uploaded, so they are vissible on one place.

You’ve got at least three options here.

  • What I would probably actually recommend, would be to check the title field at the time you’re saving the form. If there wasn’t a title supplied, get the file name from the file field, update the title field, and then save the record again. This prevents the need to do the work everytime that row is queried.

  • You could create a model method that converts the value and returns the file name. You would then call that model method in the template.

  • You could create a custom tag to basically do the work above.