Skip to main content

Attach files to Django models

Project description

Django Anchor

Test Documentation Status

A reusable Django app to handle files attached to models, inspired by Ruby on Rails' excellent Active Storage.

Features

  • Attach images and other files to your models. Supports one or more individual files per model as well as multiple ordered collections of files.
  • Optimized storage. Deduplicates files for optimized storage
  • Display files in templates. Render resized thumbnails and optimized versions of your images in templates via a template tag.
  • Reduce external dependencies. Django anchor doesn't need any external services and works Django's local file storage.

Limitations

  • Files are prefixed with a random string which makes the URLs for them hard to guess, but they are currently not protected against unauthorized attacks.
  • It only works with Django storage classes in which files are accessible via the file system, i.e. where the path property of a file is implemented.
  • It currently depends on Huey for background processing.

Future work

  • Remove dependency on base58
  • Implement private file links (maybe via signed URLs?)
  • Support for async/delayed variant generation
  • Reduce number of dependencies:
    • Make PIL dependency optional

Installation

Django-anchor is compatible with Django >= 4.2 and Python >= 3.10.

  1. Add the django-anchor package to your dependencies. You can do this by running:

    pip install django-anchor
    

    or by adding django-anchor to your requirements.txt or pyproject.toml files if you have one.

  2. Add anchor to settings.INSTALLED_APPS

In addition, if you wish to create image variants, a Pillow >= 8.4 should be available in your system.

Usage

💡 Check out the demo Django project for inspiration and the Getting Started guide in the documentation.

Adding files to models

The easiest way to add a file to a model is to add a BlobField to it:

from django.db import models
from anchor.models.fields import BlobField


class Movie(models.Model):
    title = models.CharField(max_length=100)

    # A compulsory field that must be set on every instance
    cover = BlobField()

    # An optional file that can be left blank
    poster = BlobField(blank=True, null=True)

Notice how the BlobField above can be customized by setting the blank and null options like any other field. It will also accept any other core field parameters.

BlobFields are ForeignKey fields under the hood, so after you've added or made changes you need to generate a migration with python manage.py makemigrations and then apply it via python manage.py migrate.

Once your migrations are applied you can assign an anchor.models.blob.Blob object to a BlobField much like you'd assign a DjangoFile object to a FileField:

from anchor.models.blob import Blob

# A new Blob objects is created and saved to the database with the file metadata
cover = Blob.objects.from_url('...')

# Make our movie point to that Blob object
movie.cover = cover
movie.save()

Using files in templates

Django anchor comes with a handy template tag to render URLs of files you've stored:

{% load anchor %}
<img src="{% blob_thumbnail movie.poster max_width=300 max_height=600 format='jpeg' %}">

The above call to blob_thumbnail will generate an optimized version of the movie's cover in JPEG format which fits inside a 300x600 rectangle. Optimized versions are generated asynchronously and if they're not ready for immediate use the original file's URL is returned instead to avoid blocking the request.

Contributing

PRs and issues are very welcome!

Check out CONTRIBUTING.md to learn how to set up the project locally.

License

This project is released under the MIT License. Check out LICENSE to get the full text of the license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_anchor-0.5.0.tar.gz (8.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_anchor-0.5.0-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

Details for the file django_anchor-0.5.0.tar.gz.

File metadata

  • Download URL: django_anchor-0.5.0.tar.gz
  • Upload date:
  • Size: 8.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for django_anchor-0.5.0.tar.gz
Algorithm Hash digest
SHA256 2f44aea7160409af58ab3cd0a1a7f44e8d4267fb97a844ef310222f492f4187a
MD5 0ba17f946711d3ab7fb93b7373cc922e
BLAKE2b-256 40cdc5aa5a778536b17b47adafba2e10d5ceea2e4838f9bf8055bbbf87fd4142

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_anchor-0.5.0.tar.gz:

Publisher: publish_to_pypi.yml on knifecake/django-anchor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_anchor-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: django_anchor-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 7.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for django_anchor-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 897983543ae36fdecb126d5133ae542736aa286d51b083c575e5f1b42c6e665c
MD5 b0f67bbda7c00249a2d98c700c5224bc
BLAKE2b-256 0f89725eba8fb237010217ba98dc5bbd21b241c5c881fb6392e906872d4502f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_anchor-0.5.0-py3-none-any.whl:

Publisher: publish_to_pypi.yml on knifecake/django-anchor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page