Django FileField: How to return filename only (in template)
Asked Answered
M

5

102

I've got a field in my model of type FileField. This gives me an object of type File, which has the following method:

File.name: The name of the file including the relative path from MEDIA_ROOT.

What I want is something like ".filename" that will only give me the filename and not the path as well, something like:

{% for download in downloads %}
  <div class="download">
    <div class="title">{{download.file.filename}}</div>
  </div>
{% endfor %}

Which would give something like myfile.jpg

Manuelmanuela answered 21/4, 2010 at 14:9 Comment(0)
M
230

In your model definition:

import os

class File(models.Model):
    file = models.FileField()
    ...

    def filename(self):
        return os.path.basename(self.file.name)
Maas answered 21/4, 2010 at 14:31 Comment(5)
worked great but needed the param to be passed into basename as self.file.name. I think it needs this as self.file is a file object rather than the string to the file.Manuelmanuela
adding the @property decorator avoids calling file.filename() and simply file.filename can be usedMountie
Surprisingly this solution even works with S3 storage backend.Panacea
It works for me. Could you please some information to explain how it works?Ohl
@user3327344 Which is the part that you have trouble with?Maas
C
60

You can do this by creating a template filter:

In myapp/templatetags/filename.py:

import os

from django import template


register = template.Library()

@register.filter
def filename(value):
    return os.path.basename(value.file.name)

And then in your template:

{% load filename %}

{# ... #}

{% for download in downloads %}
  <div class="download">
      <div class="title">{{download.file|filename}}</div>
  </div>
{% endfor %}
Cathleencathlene answered 28/10, 2010 at 19:29 Comment(3)
This is also a nice approach. Perhaps a little more portable?Pencil
As you wrote the filter it should be {{download|filename}}Regularly
don’t forget the __init__.py file to ensure the templatetags directory is treated as a Python package.Galileo
G
3

You could also use the cut filter in your template

{% for download in downloads %}
  <div class="download">
    <div class="title">{{download.file.filename|cut:'remove/trailing/dirs/'}}</div>
  </div>
{% endfor %}
Gunning answered 9/12, 2021 at 18:50 Comment(0)
G
0

A modern solution using Pathlib:

from pathlib import Path

class File(models.Model):
    file = models.FileField()
    ...

    def filename(self):
        return Path(self.file.name).name
Galantine answered 27/3, 2024 at 18:55 Comment(0)
V
-3

You can access the filename from the file field object with the name property.

class CsvJob(Models.model):

    file = models.FileField()

then you can get the particular objects filename using.

obj = CsvJob.objects.get()
obj.file.name property
Villeneuve answered 16/9, 2016 at 9:0 Comment(1)
Accessing obj.file.name returns the entire path in the media dir, e.g. it returns tasks/132/foo.jpg rather than foo.jpg.Dybbuk

© 2022 - 2025 — McMap. All rights reserved.