django - How to insert the content of uploaded file in template?

django, django-templates, python

Solution

You can define a method for your class that have `FileField`, if you want to do more than `read` method of `FileField` do, for for example `display_text_file`, and then in template call it.

Models:

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    text = models.FileField(max_length=100, upload_to='.')

def display_text_file(self):
    with open(self.text.path) as fp:
        return fp.read().replace('\n', '<br>')

Views:

def show_files(request):
    objects = MyModel.objects.all()
    return render_to_response('show_files.html', {'objects': objects},
                              context_instance=RequestContext(request))

Templates:

{% for obj in objects %}

 <p>
   file name: {{obj.name}} <br>
   file content: {{obj.display_text_file}}
 </p>

{% endfor %}

For ways of opening file, in `display_text_file`, all of these ways works for me:

def display_text_file(self):
    with open(self.text.path) as fp:
        return fp.read().replace('\n', '<br>')

def display_text_file(self):
    self.text.open() # reset the pointer of file, needs if you need to read file more than once, in a request.
    return self.text.read().replace('\n', '<br>')

def display_text_file(self):
    self.text.open() # reset the pointer of file, needs if you need to read file more than once, in a request.
    return self.text.file.read().replace('\n', '<br>')

Type of `self.text` is `django.db.models.fields.files.FieldFile` and having following methods:

['DEFAULT_CHUNK_SIZE', 'chunks', 'close', 'closed', 'delete', 'encoding', 'field', 'file', 
'fileno', 'flush', 'instance', 'isatty', 'multiple_chunks', 'name', 'newlines', 'open', 'path', 
'read', 'readinto', 'readline', 'readlines', 'save', 'seek', 'size', 'softspace', 'storage', 'tell', 
'truncate', 'url', 'write', 'writelines', 'xreadlines']

And type of `self.text.file` is `django.core.files.base.File` and having following methods:

['DEFAULT_CHUNK_SIZE', 'chunks', 'close', 'closed', 'encoding', 'file', 
'fileno', 'flush', 'isatty', 'mode', 'multiple_chunks', 'name', 'newlines', 'open', 
'read', 'readinto', 'readline', 'readlines', 'seek', 'size', 'softspace', 'tell', 
'truncate', 'write', 'writelines', 'xreadlines']

And both of them have `read` method.

Problem

Say I've stored a text file in FileField. Now I want to display its content on the webpage. I read the django template document but didn't find a way to do this. Of course I can do `content = f.read()` in my views and pass `content` to the template. Is there a better way? Thank you! `better way` means I could get the job done by passing `MyModel.objects.all()` to template.I can't `read` a file in template, but there should be some kind of hacks for this. edit I've tried: ``` def display_html(self): content = self.html_file.read() print(content) return content ``` but nothing displayed... final edit It's very strange that the following code works ``` class MyModel(models.Model): name = models.CharField() text = models.FileField() def display_text_file(self): fp = open(self.text.path) return fp.read().replace('\n', '<br>') ``` However what I regard as equivalent doesn't work: ``` class MyModel(models.Model): name = models.CharField() text = models.FileField() def display_text_file(self): return self.text.read().replace('\n', '<br>') # neither do self.text.read().decode().replace('\n', '<br>') ``` I really want to know the reason.

Original source

Related problems