101

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

daaawx
  • 3,273
  • 2
  • 17
  • 16
John
  • 21,047
  • 43
  • 114
  • 155

4 Answers4

224

In your model definition:

import os

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

    def filename(self):
        return os.path.basename(self.file.name)
Ludwik Trammer
  • 24,602
  • 6
  • 66
  • 90
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 %}
rz.
  • 19,861
  • 10
  • 54
  • 47
3

You could also use 'cut' in your template

{% for download in downloads %}
  <div class="download">
    <div class="title">{{download.file.filename|cut:'remove/trailing/dirs/'}}</div>
  </div>
{% endfor %}
-2

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
DeadDjangoDjoker
  • 534
  • 2
  • 8
  • 20
  • Accessing `obj.file.name` returns the entire path in the media dir, e.g. it returns `tasks/132/foo.jpg` rather than `foo.jpg`. – shacker Apr 07 '19 at 06:08