Skip to content

Instantly share code, notes, and snippets.

@avoiney
Last active June 12, 2021 12:46
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save avoiney/5248673 to your computer and use it in GitHub Desktop.
Save avoiney/5248673 to your computer and use it in GitHub Desktop.
Manually associate an existing file to a model FileField
# Assuming you have a Article Model like this
# class Article(models.Model):
# ... Some field
# media = models.FileField(upload_to="path_to_inner_media_folder", blank=True)
from django.core.files.base import ContentFile
import os
# Create an article with the associated model
new_article = Article()
original_file_path = 'path'
new_file_path = 'new_path'
fh = open(original_file_path, "r")
if fh:
# Get the content of the file
file_content = ContentFile(fh.read())
# Set the media attribute of the article, but under an other path/filename
new_article.media.save(new_file_path, file_content)
# Save the article
new_article.save()
# Close the file and delete it
fh.close()
if fh.closed:
os.remove(unicode(fh.name))
del fh
@nosahama
Copy link

nosahama commented Nov 7, 2018

With reference to line 20, on line 22, i don't think you need to call save() again, unless you change other model fields. If it's just the file field, then line 20 is enough. What'd you think?

@CarliJoy
Copy link

I would suggest:

# Assuming you have a Article Model like this
# class Article(models.Model):
#   ... Some field
# 	media = models.FileField(upload_to="path_to_inner_media_folder", blank=True)

from django.core.files.base import ContentFile
import os

# Create an article with the associated model
new_article = Article()

original_file_path = 'path'
new_file_path = 'new_path'

# With closes properly also on exceptions
with open(original_file_path, "rb") as fh
	# Get the content of the file, we also need to close the content file
	with ContentFile(fh.read()) as 	file_content:
	# Set the media attribute of the article, but under an other path/filename
		new_article.media.save(new_file_path, file_content)
		# Save the article
		new_article.save()

os.remove(unicode(fh.name))
del fh

@andrestone
Copy link

andrestone commented Sep 19, 2019

Isn't there a way to simply associate the FileField to the actual file?

@ncopiy
Copy link

ncopiy commented Oct 9, 2019

@andrestone that was works for me:

file_path = "..."  # it should be relative path to your settings.MEDIA_ROOT  
article.file = file_path  
article.save()```

@avoiney
Copy link
Author

avoiney commented Oct 29, 2019

@CarliJoy much more better! Thanks!

@ncopiy It may works if the file is already saved in the dir your model file field expect.
But if you want to deal with InMemoryFile or StringIO content, this snippets should handle the model file field base path you defined. It a little more complicated though, so it depends on your needs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment