Using GridFSStorage
GridFS is a specification for storing and retrieving files that exceed the BSON-document size limit of 16 MB.
GridFSStorage backend for Djongo aims to add a GridFS storage to upload files to using Django’s file fields.
We first define our basic models. In the tutorials, we use the example used in the official Django documentation. The documentation talks about 3 models that interact with each other: Blog, Author and Entry. To make the example clearer, few fields from the original models are omitted.
## models.py
from djongo import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
avatar = models.ImageField(upload_to='authors')
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
featured_image = models.ImageField(upload_to='entries')
def __str__(self):
return self.headline
GridFS Storage
The Author
and Entry
models define a field type ImageField
. Until now, when you upload files, those files will be uploaded to MEDIA_ROOT/authors
and MEDIA_ROOT/entries
directories.
So, what happens if you want to save those files into database? That is when appears GridFS to the rescue!.
In your models.py
file you could probably do:
## models.py
from django.conf import settings
# Add the import for GridFSStorage
from djongo.storage import GridFSStorage
# Define your GrifFSStorage instance
grid_fs_storage = GridFSStorage(collection='myfiles', base_url=''.join([settings.BASE_URL, 'myfiles/']))
In Author
change avatar
field definition for this:
avatar = models.ImageField(upload_to='authors', storage=grid_fs_storage)
In Entry
change avatar
field definition for this:
featured_image = models.ImageField(upload_to='entries', storage=grid_fs_storage)
And, that’s all, when you upload avatar
for Author
it will be saved in collection myfiles.authors.files
or when you upload featured_image
for Entry
it will be saved in collection myfiles.entries.files
Retriving values
Suppose that you have saved some documents in your collection related to Author model, so if you want to retrieve one of them, you could probably do:
# in a python console
>>> author = Author.object.get(id=1)
>>> print(author)
{ 'id': 1, 'name': 'Lisa Stoner', 'email': 'lisa.stoner@nomail.local', 'avatar': 'http://mysite.local/myfiles/5dc880e06a8e6a7effa592a7'}
As you can see, the value that is retrieved in avatar
field is the _id
related to the saved image|file. In this case you get a url because you probably have in your settings file the following:
UPLOADED_FILES_USE_URL = True