Escher Escher - 17 days ago 10
Python Question

How to update a ContentFile's content (by overwriting the file)

I'm trying to keep the same filename of a

FileField
in my
UpdateView
when I update the file content.

It's a css file that
CreateView
generates by rendering a template with the form data as the context. Here's an extract of that logic:

instance = form.save(commit=False)
t = TemplateResponse(self.request, 'base.css', {"cssform": form})
t.render()
css_string = t.content
file_content = ContentFile(css_string)
instance.css_file.save(file_name, file_content)


I'm not having the same success with the
UpdateView
:

def form_valid(self, form):
instance = self.object
filename = instance.css_file
t = TemplateResponse(self.request, 'base.css', {"cssform": form})
t.render()
css_string = t.content
filedata = ContentFile(css_string)
instance.css_file.save(filename, filedata)
super(CSSUpdate, self).save(form)


The error is:


join() argument must be str or bytes, not 'FieldFile'


The error is provoked on this line:

instance.css_file.save(filename, filedata)


The traceback is short:


Traceback:

File "/usr/lib/python3.5/posixpath.py" in join
82. if b.startswith(sep):


How do I overwrite that old file with my new content?
I'm using django 1.10, python 3.5

Answer

instance.css_file is a FieldFile object, not a filename. You should use the name instead:

def form_valid(self, form):
    instance = self.object
    filename = instance.css_file.name
    ...
    instance.css_file.save(filename, filedata)
    super(CSSUpdate, self).save(form)