Webservers don't support gridfs by default. So you need to do something on your own. Most people seem to use some form of Django view at least for development (see below), there is a gridfs module for nginx [1] which I haven't used or tried. I do have some very unfinished stuff to build a full blown gridfs http server (including support for byte ranges, etags, streaming support for very large files etc.) in Erlang if you need something that can be build to scale. For a normal website or blog a Django view should be fine though.
A simple Django view might look like this:
# views.py
import time
from mongoengine.connection import get_db
from gridfs import GridFS, NoFile
from bson.objectid import ObjectId
from django.http import Http404, HttpResponse
from django.utils.http import http_date
def serve_file(request, file_id):
fs = GridFS(db)
try:
f = fs.get(ObjectId(file_id))
except NoFile:
fs = GridFS(db, collection='images') # mongoengine stores images in a separate collection by default
try:
f = fs.get(ObjectId(file_id))
except NoFile:
raise Http404
response = HttpResponse(f.read(), content_type=f.content_type)
timestamp = time.mktime(gridout.upload_date.timetuple())
response["Last-Modified"] = http_date(timestamp)
# add other header data like etags etc. here
return response
#urls.py
urlpatterns += patterns('',
url(r'^gridfs/(?P<file_id>[0-9a-f]{24})/$', 'gridfs.views.serve_file'),
)
Note that this view mostly ignores everything from mongoengine and will load the file completely into memory, so if you need to serve large files this is a bad way to do it. To get a URL in your template you can do something like {% url 'gridfs.views.serve_file' mydoc.gridfile_attr %} where gridfile_attr is something like
@property
def gridfile_attr(self):
return str(self.the_file.grid_id) # otherwise you will get ObjectId('5227a0c157a020b07eddc4aa') as parameter for url which will never match
If you want to do more with your file before serving it, you can in most cases use the file attribute from your document, that is for most cases file like enough to be used in image libraries for example and if you generate some kind of normal file you can use the normal Django stuff. There is also a storage engine provided with mongoengine. I admit that I mostly try to avoid that though, so I'm not a lot of help there.
The function above uses pymongo directly, see the gridfs docs [2] if you want to use names instead of object ids. Or load the complete document holding the file first and then serve the file from there if you need more checks.
regards,
Jan