Provide a Document model including a FileField and a custom storage. Uploaded documents live outside of MEDIA_ROOT and must be downloaded through a view that does security checks. Using django-autocomplete-light and django-generic-m2m, allow to attach any object to it.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
documents Fixed typo that caused wrong filename Jul 12, 2012
test_project Added south to test_project requirements Jul 12, 2012



This simple app provides:

  • a Document model with:
    • a generic many to many relation
    • a file field that uploads to a private directory
    • a method get_download_url()
  • a view to download a document which allows custom security checks through a signal
  • a signal, document_pre_download, that is emited by the download view, and which responds with 503 if emiting the signal raises a DownloadForbidden exception
  • clean admin integration
  • south support


Run the demo of a release in a temporary folder:


cd /tmp
rm -rf django-documents documents_env
virtualenv documents_env
source documents_env/bin/activate
pip install django-documents==$DOCUMENTS_VERSION
git clone
cd django-documents/test_project
pip install -r requirements.txt
./ runserver

Login with test / test.

Or current development sources (might be broken):

cd /tmp
rm -rf django-documents documents_env
virtualenv documents_env
source documents_env/bin/activate
pip install -e git+
cd documents_env/src/documents/test_project
pip install -r requirements.txt
./ runserver

Install django-generic-m2m

Refer to django-generic-m2m installation documentation, do "Installation" and "Adding to your Django Project".

Install autocomplete_light

Refer to django-autocomplete-light installation documentation, do "Quick install" and "Quick admin integration".

Install django-documents

Download the lastest release:

pip install django-documents

Or install the development version:

pip install -e git+

Add to settings.INSTALLED_APPS:


If using south, run:

./ migrate

Else, run:

./ syncdb

Add to

url(r'^documents/', include('documents.urls')),

Set settings.DOCUMENTS_UPLOAD_TO to the absolute path where uploads should be stored. This must be a private directory.

Prepare the generic many to many autocomplete

Register a generic autocomplete, with name "AutocompleteDocumentRelations". There is an example in test_project which is imported in Refer the django-autocomplete-light documentation about the registry for alternative methods.

If the project already uses django-generic-m2m and django-autocomplete-light, a good solution is to re-register the project's generic autocomplete with name='AutocompleteDocumentRelations', ie.:

# your project specific autocomplete
class AutocompleteProject(autocomplete_light.AutocompleteGenericBase):
    # ....

# register for your project needs

# registery for documents relations

Secure your documents

Connect to document_pre_import, for example:

# project specific document permissions
import documents
def document_security(sender, request, document, **kwargs):
    if not request.user.is_staff:
        raise documents.DownloadForbidden()

Display documents related to a model

Use get_related_documents() from Python:

from documents.models import get_related_documents

your_model = YourModel.objects.get(pk=XXX)

related_documents = get_related_documents(your_model)

Or from a template:

{% load documents_tags %}

{% for document in your_model|get_related_documents %}
    {{ document }}
{% endfor %}

Note that get_related_documents() returns a QuerySet, ie. you can get a count:


Or from a template:

{% with related_documents=your_model|get_related_documents %}
    {{ related_documents.count }}
{% endwith %}