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.
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



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 %}