def create_sorted_many_related_manager(superclass, rel, *args, **kwargs):
    RelatedManager = create_forward_many_to_many_manager(
        superclass, rel, *args, **kwargs)

    class SortedRelatedManager(RelatedManager):
        def get_queryset(self):
            # We use ``extra`` method here because we have no other access to
            # the extra sorting field of the intermediary model. The fields
            # are hidden for joins because we set ``auto_created`` on the
            # intermediary's meta options.
            try:
                return self.instance._prefetched_objects_cache[self.prefetch_cache_name]
            except (AttributeError, KeyError):
                # Django 1.5 support.
                if not hasattr(RelatedManager, 'get_queryset'):
                    queryset = super(SortedRelatedManager, self).get_query_set()
                else:
                    queryset = super(SortedRelatedManager, self).get_queryset()
                return queryset.extra(order_by=['%s.%s' % (
                    rel.through._meta.db_table,
                    rel.through._sort_field_name,
                )])

        get_query_set = get_queryset

        if not hasattr(RelatedManager, '_get_fk_val'):
            @property
            def _fk_val(self):
                # Django 1.5 support.
                if not hasattr(self, 'related_val'):
                    return self._pk_val
                return self.related_val[0]

        def get_prefetch_queryset(self, instances, queryset=None):
            # Django 1.5 support. The method name changed since.
            if django.VERSION < (1, 6):
                result = super(SortedRelatedManager, self).get_prefetch_query_set(instances)
            # Django 1.6 support. The queryset parameter was not supported.
            elif django.VERSION < (1, 7):
                result = super(SortedRelatedManager, self).get_prefetch_queryset(instances)
            else:
                result = super(SortedRelatedManager, self).get_prefetch_queryset(instances, queryset)
            queryset = result[0]
            queryset.query.extra_order_by = [
                '%s.%s' % (
                    rel.through._meta.db_table,
                    rel.through._sort_field_name,
                )]
            return (queryset,) + result[1:]

        get_prefetch_query_set = get_prefetch_queryset

        def set(self, objs, **kwargs):
            # Choosing to clear first will ensure the order is maintained.
            kwargs['clear'] = True
            super(SortedRelatedManager, self).set(objs, **kwargs)
        set.alters_data = True

        def _add_items(self, source_field_name, target_field_name, *objs):
            # source_field_name: the PK fieldname in join table for the source object
            # target_field_name: the PK fieldname in join table for the target object
            # *objs - objects to add. Either object instances, or primary keys of object instances.

            # If there aren't any objects, there is nothing to do.
            from django.db.models import Max, Model
            if objs:
                # Django uses a set here, we need to use a list to keep the
                # correct ordering.
                new_ids = []
                for obj in objs:
                    if isinstance(obj, self.model):
                        if not router.allow_relation(obj, self.instance):
                            raise ValueError(
                                'Cannot add "%r": instance is on database "%s", value is on database "%s"' %
                                (obj, self.instance._state.db, obj._state.db)
                            )
                        if hasattr(self, '_get_fk_val'):  # Django>=1.5
                            fk_val = self._get_fk_val(obj, target_field_name)
                            if fk_val is None:
                                raise ValueError('Cannot add "%r": the value for field "%s" is None' %
                                                 (obj, target_field_name))
                            new_ids.append(self._get_fk_val(obj, target_field_name))
                        else:  # Django<1.5
                            new_ids.append(obj.pk)
                    elif isinstance(obj, Model):
                        raise TypeError(
                            "'%s' instance expected, got %r" %
                            (self.model._meta.object_name, obj)
                        )
                    else:
                        new_ids.append(obj)

                db = router.db_for_write(self.through, instance=self.instance)
                manager = self.through._default_manager.using(db)
                vals = (manager
                        .values_list(target_field_name, flat=True)
                        .filter(**{
                            source_field_name: self._fk_val,
                            '%s__in' % target_field_name: new_ids,
                        }))
                for val in vals:
                    if val in new_ids:
                        new_ids.remove(val)
                _new_ids = []
                for pk in new_ids:
                    if pk not in _new_ids:
                        _new_ids.append(pk)
                new_ids = _new_ids
                new_ids_set = set(new_ids)

                if self.reverse or source_field_name == self.source_field_name:
                    # Don't send the signal when we are inserting the
                    # duplicate data row for symmetrical reverse entries.
                    signals.m2m_changed.send(sender=rel.through, action='pre_add',
                        instance=self.instance, reverse=self.reverse,
                        model=self.model, pk_set=new_ids_set, using=db)

                # Add the ones that aren't there already
                with atomic(using=db):
                    fk_val = self._fk_val
                    source_queryset = manager.filter(**{'%s_id' % source_field_name: fk_val})
                    sort_field_name = self.through._sort_field_name
                    sort_value_max = source_queryset.aggregate(max=Max(sort_field_name))['max'] or 0

                    manager.bulk_create([
                        self.through(**{
                            '%s_id' % source_field_name: fk_val,
                            '%s_id' % target_field_name: pk,
                            sort_field_name: sort_value_max + i + 1,
                        })
                        for i, pk in enumerate(new_ids)
                    ])

                if self.reverse or source_field_name == self.source_field_name:
                    # Don't send the signal when we are inserting the
                    # duplicate data row for symmetrical reverse entries.
                    signals.m2m_changed.send(sender=rel.through, action='post_add',
                        instance=self.instance, reverse=self.reverse,
                        model=self.model, pk_set=new_ids_set, using=db)

    return SortedRelatedManager
dataset/ETHPy150Open gregmuellegger/django-sortedm2m/sortedm2m/fields.py/create_sorted_many_related_manager/original