Install & Compatibility
Where this runs
tested against v4.0.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 0.000s · 18MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 1.5s · import 0.000s · 19MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
SortedManyToManyField
✓ from sortedm2m.fields import SortedManyToManyField
✗ from sortedm2m import SortedManyToManyField
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}")
Debug
Known issues
breakingVersion 4.0.0 of `django-sortedm2m` dropped support for older, outdated versions of Django and Python. Ensure your project meets the new requirements (Django 4.x, 5.0, 5.1 and Python 3.6+) before upgrading.fixUpgrade your Django and Python versions to supported ones (e.g., Django >= 4.2, Python >= 3.6) or pin `django-sortedm2m` to an earlier compatible version (e.g., `django-sortedm2m<4.0.0`).
affects: 4.0.0+
breakingWhen upgrading `django-sortedm2m` with Django 5.1, versions prior to 4.0.0 may encounter an `AttributeError: 'ManyToManyRel' object has no attribute 'is_hidden'` due to a change in Django's internal API.fixUpgrade to `django-sortedm2m` version 4.0.0 or later, which includes a fix for this Django 5.1 incompatibility.
affects: <4.0.0 with Django 5.1
gotchaWhen migrating an existing `ManyToManyField` to a `SortedManyToManyField` (or vice-versa), Django's `makemigrations` will generate an `AlterField` operation. This must be manually changed in the migration file to `AlterSortedManyToManyField` (imported from `sortedm2m.operations`) to ensure correct database schema changes.fixAfter running `makemigrations`, edit the generated migration file. Locate the `migrations.AlterField` operation and replace it with `operations.AlterSortedManyToManyField`. Ensure you add `from sortedm2m.operations import AlterSortedManyToManyField` to the migration file.
affects: All versions
gotchaFor proper functioning of the custom sortable widget in the Django admin, ensure 'sortedm2m' is included in your `INSTALLED_APPS` setting. Additionally, avoid listing `SortedManyToManyField` fields in `filter_horizontal` or `filter_vertical` tuples in your `ModelAdmin` definitions, as this can interfere with the custom widget's functionality.fixAdd `'sortedm2m'` to `INSTALLED_APPS`. Remove affected fields from `filter_horizontal` or `filter_vertical`. Consider using `raw_id_fields` if you need a simpler input for IDs.
affects: All versions
Upgrade
Version history
4.0.0latest on PyPI · released Aug 11, 2024
Audit
Dependencies
DjangorequiredCore framework dependency. Version 4.0.0 of django-sortedm2m supports Django 4.x, 5.0, and 5.1, and Python 3.6+.