Sometimes it’s useful to populate your database with existing data for testing
or whatever.
For simple data types such as text, it’s simply a matter of inserting
gibberish into the database.
For images, it’s better if you can insert real images to
mimick a real world scenario for your app’s user interface.
Let’s see how you’d do that.
A dummy model
First, we need a model to work with:
class Post(models.Model):
image = models.ImageField(upload_to="user_uploads/")
What needs to be done
To store an existing file into the image
field, you need to take 3 steps:
- Create an
ImageFile
instance from your file object.
- Feed this
ImageFile
instance to the file
argument of the image
field.
- Save the model.
Django File objects
Django has different file classes for different types of files.
Here, I will use ImageFile
because I’m saving to an ImageField
.
To instantiate a File
object, you need to load your existing file in memory.
If you have your file saved locally, simply open()
it:
with open('your-image.jpeg', 'rb') as existing_file:
django_image_file = ImageFile(file=existing_file, name='filename.jpeg')
post = Post(image=django_image_file)
post.full_clean()
post.save()
Very simple.
If you need to fetch a file from the Internet, you can use requests:
res = requests.get('https://your-url.io/image.jpeg')
django_image_file = ImageFile(file=BytesIO(res.content), name='filename.jpeg')
post = Post(image=django_image_file)
post.full_clean()
post.save()
Here, I used BytesIO to feed the file to ImageFile
without having to save it
first. You can also save the file to a temorary location using NamedTemporaryFile
or your own method if necessary.
If you’re trying to store large files, you should use the stream=True
when
downloading the file then save it to a temporary location to prevent requests
from loading the entire file in memory.
And that’s how you save existing files to Django models.