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/f开发者_JAVA百科ile1.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?
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:]
this is kind of cheating:
{{ resource.file_name|cut:resource.file_name.path }}
not tested.
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 }}
精彩评论