views:

241

answers:

3

I have the following django model:

RESOURCE_DIR = os.path.join(settings.MEDIA_ROOT, 'resources')

class Resource(models.Model):
    title = models.CharField(max_length=255)
    file_name = models.FilePathField(path=RESOURCE_DIR, recursive=True)

and I want to give the URL to the file in a template so that the user can view it or download it.

If I use {{ resource.file_name }} in the template it outputs the full path of the file on the server, e.g. if RESOURCE_DIR='/home/foo/site_media/media' it outputs '/home/foo/site_media/media/pdf/file1.pdf' whereas what I want is 'pdf/file1.pdf'. In the admin or in a modelform the option is displayed as '/pdf/file1.pdf' in the select widget. So obviously it is possible to do what I asking. Of course the extra slash is not important. If I were setting recursive=False then I could just remove the part of the path before the last slash.

How can I get the same result as the modelform or admin?

A: 

this is kind of cheating:

{{ resource.file_name|cut:resource.file_name.path }}

not tested.

Brandon H
{{ resource.file_name.path }} is an empty string so this doesn't work. I think this is because in the view resource.file_name is a unicode string and not a FilePathField. I have been trying the extract the path of the FilePathField via resource._meta but as I am pretty new to django it is not easy to figure out. thanks for trying
gaumann
A: 

I figured out that you can retrieve the path argument to the FilePathField using resource._meta.get_field('file_name').path It seems best to do this in the model. So the model becomes:

RESOURCE_DIR = os.path.join(settings.MEDIA_ROOT, 'resources')

class Resource(models.Model):
    title = models.CharField(max_length=255)
    file_name = models.FilePathField(path=RESOURCE_DIR, recursive=True)

    def url(self):
        path = self._meta.get_field('file_name').path
        return self.file_name.replace(path, '', 1)

then in the template you can put: {{ MEDIA_URL }}resources{{ resource.url }}

gaumann
A: 

the below leaves in the leading path separator, which may not be the forward slash a url needs

def url(self):
    path = self._meta.get_field('file_name').path
    return self.file_name.replace(path, '', 1)

so slight improvement

def url(self):
        path = self._meta.get_field('icon').path
        return "/" + self.icon[len(path)+1:]