Django Sorted Many-to-Many

4.0.0 · active · verified Thu Apr 16

django-sortedm2m is a drop-in replacement for Django's built-in ManyToManyField that preserves the order of related objects. It is actively maintained by the Jazzband community, with version 4.0.0 being the latest, offering support for recent Django and Python versions. Releases are frequent, focusing on compatibility updates, bug fixes, and minor enhancements.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define models using `SortedManyToManyField` and how to add and retrieve related objects, maintaining their order. It also shows how to explicitly set the order using the `set()` method on the manager. Remember to add 'sortedm2m' to your `INSTALLED_APPS`.

import os
import django
from django.conf import settings
from django.db import models

# Minimal Django settings for demonstration
settings.configure(
    INSTALLED_APPS=[
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'sortedm2m',
        'my_app', # Your app name
    ],
    DATABASES={
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': ':memory:',
        }
    },
    MEDIA_ROOT=os.path.join(os.path.dirname(__file__), 'media'),
    STATIC_URL='/static/',
    DEBUG=True,
    USE_TZ=True
)
django.setup()

# Define your models
class Photo(models.Model):
    name = models.CharField(max_length=50)
    image = models.ImageField(upload_to='photos', blank=True, null=True)

    def __str__(self):
        return self.name

class Gallery(models.Model):
    name = models.CharField(max_length=50)
    photos = SortedManyToManyField(Photo)

    def __str__(self):
        return self.name

# Example usage:
if __name__ == '__main__':
    # Create some photos
    photo1 = Photo.objects.create(name='Sunset View')
    photo2 = Photo.objects.create(name='Mountain Hike')
    photo3 = Photo.objects.create(name='City Lights')

    # Create a gallery
    gallery = Gallery.objects.create(name='Travel Memories')

    # Add photos in a specific order
    gallery.photos.add(photo2)
    gallery.photos.add(photo1)
    gallery.photos.add(photo3)

    print(f"Gallery: {gallery.name}")
    print("Photos in order:")
    for photo in gallery.photos.all():
        print(f"- {photo.name}")

    # Reorder photos (example: move photo3 to the beginning)
    gallery.photos.set([photo3.pk, photo2.pk, photo1.pk])
    print("\nPhotos after reordering:")
    for photo in gallery.photos.all():
        print(f"- {photo.name}")

    # Example with filtering and adding
    new_gallery = Gallery.objects.create(name='Nature Wonders')
    for photo in Photo.objects.order_by('name'):
        new_gallery.photos.add(photo)
    print(f"\nNew Gallery: {new_gallery.name}")
    print("Photos added by name order:")
    for photo in new_gallery.photos.all():
        print(f"- {photo.name}")

view raw JSON →