Save Existing Files to Django Models

Save Existing Files to Django Models

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:

  1. Create an ImageFile instance from your file object.
  2. Feed this ImageFile instance to the file argument of the image field.
  3. 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.