GithubHelp home page GithubHelp logo

jazzband / django-admin-sortable Goto Github PK

View Code? Open in Web Editor NEW
566.0 17.0 137.0 1.74 MB

Generic drag-and-drop ordering for objects and tabular inlines in Django Admin

License: Other

Python 71.54% CSS 0.93% HTML 27.53%

django-admin-sortable's Introduction

Looking for maintainers

If you're interested in helping maintain and expand this library, please reach out to me. Due to other responsibilities and circumstances, I have basically no time to address issues for this codebase. I would greatly appreciate the help!

Django Admin Sortable

PyPI version Python versions Build Status

This project makes it easy to add drag-and-drop ordering to any model in Django admin. Inlines for a sortable model may also be made sortable, enabling individual items or groups of items to be sortable.

If you find Django Admin Sortable to be helpful, consider buying me a coffee!

Sorting model instances with a sortable parent:

sortable-models

Sorting inlines:

sortable-inlines

Supported Django Versions

For Django 4 use the latest version

For Django 3 use 2.2.4

For Django 1.8.x < 3.0, use 2.1.8.

For Django 1.5.x to 1.7.x, use version 2.0.18.

Other notes of interest regarding versions

django-admin-sortable 1.5.2 introduced backward-incompatible changes for Django 1.4.x

django-admin-sortable 1.6.6 introduced a backward-incompatible change for the sorting_filters attribute. Please convert your attributes to the new tuple-based format if you haven't already.

django-admin-sortable 1.7.1 and higher are compatible with Python 3.

django-admin-sortable 2.1.6 has a bug. Please don't use it :)

Installation

  1. $ pip install django-admin-sortable

--or--

Download django-admin-sortable from source

  1. Unzip the directory and cd into the uncompressed project directory
    • Optional: Enable your virtualenv
  2. Run $ python setup.py install or add adminsortable to your PYTHONPATH.

Configuration

  1. Add adminsortable to your INSTALLED_APPS.
  2. Ensure django.template.context_processors.static is in your TEMPLATES["OPTIONS"]["context_processors"].
    • (In older versions of Django, ensure django.core.context_processors.static is in TEMPLATE_CONTEXT_PROCESSORS instead.)
  3. Ensure that CSRF_COOKIE_HTTPONLY has not been set to True, as django-admin-sortable is currently incompatible with that setting.

Static Media

Preferred: Use the staticfiles app

Alternate: Copy the adminsortable folder from the static folder to the location you serve static files from.

Testing

Have a look at the included sample_project to see working examples. The login credentials for admin are: admin/admin

When a model is sortable, a tool-area link will be added that says "Change Order". Click this link, and you will be taken to the custom view where you can drag-and-drop the records into order.

Inlines may be drag-and-dropped into any order directly from the change form.

Usage

Models

To add "sortability" to a model, you need to inherit SortableMixin and at minimum, define:

  • The field which should be used for Meta.ordering, which must resolve to one of the integer fields defined in Django's ORM:

    • PositiveIntegerField
    • IntegerField
    • PositiveSmallIntegerField
    • SmallIntegerField
    • BigIntegerField
  • ⚠️ Meta.ordering must only contain one value, otherwise, your objects will not be sorted correctly.

  • ⚠️ IMPORTANT: You must name the field you use for ordering something other than "order_field" as this name is reserved by the SortableMixin class.

  • It is recommended that you set editable=False and db_index=True on the field defined in Meta.ordering for a seamless Django admin experience and faster lookups on the objects.

Sample Model:

# models.py
from adminsortable.models import SortableMixin

class MySortableClass(SortableMixin):
    title = models.CharField(max_length=50)

    class Meta:
        verbose_name = 'My Sortable Class'
        verbose_name_plural = 'My Sortable Classes'
        ordering = ['the_order']


    # define the field the model should be ordered by
    the_order = models.PositiveIntegerField(default=0, editable=False, db_index=True)

    def __unicode__(self):
        return self.title

Support for models that don't use an AutoField for their primary key are also supported in version 2.0.20 or higher.

Common Use Case

A common use case is to have child objects that are sortable relative to a parent. If your parent object is also sortable, here's how you would set up your models and admin options:

# models.py
from adminsortable.fields import SortableForeignKey

class Category(SortableMixin):
    class Meta:
        ordering = ['category_order']
        verbose_name_plural = 'Categories'

    title = models.CharField(max_length=50)

    # ordering field
    category_order = models.PositiveIntegerField(default=0, editable=False, db_index=True)

class Project(SortableMixin):
    class Meta:
        ordering = ['project_order']

    category = SortableForeignKey(Category)
    title = models.CharField(max_length=50)

    # ordering field
    project_order = models.PositiveIntegerField(default=0, editable=False, db_index=True)

    def __unicode__(self):
        return self.title

# admin.py
from adminsortable.admin import SortableAdmin

from your_app.models import Category, Project

admin.site.register(Category, SortableAdmin)
admin.site.register(Project, SortableAdmin)

Sortable Model With Non-Sortable Parent

Sometimes you might have a parent model that is not sortable, but has child models that are. In that case define your models and admin options as such:

from adminsortable.fields import SortableForeignKey

# models.py
class Category(models.Model):
    class Meta:
        verbose_name_plural = 'Categories'

    title = models.CharField(max_length=50)
    ...

class Project(SortableMixin):
    class Meta:
        ordering = ['project_order']

    category = SortableForeignKey(Category)
    title = models.CharField(max_length=50)

    # ordering field
    project_order = models.PositiveIntegerField(default=0, editable=False, db_index=True)

    def __unicode__(self):
        return self.title

# admin
from adminsortable.admin import NonSortableParentAdmin, SortableStackedInline

from your_app.models import Category, Project

class ProjectInline(SortableStackedInline):
    model = Project
    extra = 1

class CategoryAdmin(NonSortableParentAdmin):
    inlines = [ProjectInline]

admin.site.register(Category, CategoryAdmin)

The NonSortableParentAdmin class is necessary to wire up the additional URL patterns and JavaScript that Django Admin Sortable needs to make your models sortable. The child model does not have to be an inline model, it can be wired directly to Django admin and the objects will be grouped by the non-sortable foreign key when sorting.

Sortable Many-to-Many Model

It is also possible to make many-to-many relations sortable, but it requires an explicit many-to-many model.

models.py:

from django.db import models
from adminsortable.models import SortableMixin
from adminsortable.fields import SortableForeignKey

class Image(models.Model):
    ...

class Gallery(models.Model):
    class Meta:
        verbose_name_plural = 'Galleries'
    ...
    images = models.ManyToManyField(
        Image,
        through_fields=('gallery', 'image'),
        through='GalleryImageRelation',
        verbose_name=_('Images')
    )

class GalleryImageRelation(SortableMixin):
    """Many to many relation that allows users to sort images in galleries"""

    class Meta:
        ordering = ['image_order']

    gallery = models.ForeignKey(Gallery, verbose_name=_("Gallery"))
    image = SortableForeignKey(Image, verbose_name=_("Image"))
    image_order = models.PositiveIntegerField(default=0, editable=False, db_index=True)

admin.py:

from django.contrib import admin
from adminsortable.admin import (SortableAdmin, SortableTabularInline)
from .models import (Image, Gallery, GalleryImageRelation)

class GalleryImageRelationInlineAdmin(SortableTabularInline):
    model = GalleryImageRelation
    extra = 1

class GalleryAdmin(NonSortableParentAdmin):
    inlines = (GalleryImageRelationInlineAdmin,)

admin.site.register(Image, admin.ModelAdmin)
admin.site.register(Gallery, GalleryAdmin)

Any non-editable space in each rendered inline will let you drag and drop them into order.

Backwards Compatibility

If you previously used Django Admin Sortable, DON'T PANIC - everything will still work exactly as before without any changes to your code. Going forward, it is recommended that you use the new SortableMixin on your models, as pre-2.0 compatibility might not be a permanent thing.

Please note however that the Sortable class still contains the hard-coded order field, and meta inheritance requirements:

# legacy model definition

from adminsortable.models import Sortable

class Project(Sortable):
    class Meta(Sortable.Meta):
        pass
    title = models.CharField(max_length=50)

    def __unicode__(self):
        return self.title

Model Instance Methods

Each instance of a sortable model has two convenience methods to get the next or previous instance:

    .get_next()
    .get_previous()

By default, these methods will respect their order in relation to a SortableForeignKey field, if present. Meaning, that given the following data:

| Parent Model 1 |               |
|                | Child Model 1 |
|                | Child Model 2 |
| Parent Model 2 |               |
|                | Child Model 3 |
|                | Child Model 4 |
|                | Child Model 5 |

"Child Model 2" get_next() would return None "Child Model 3" get_previous would return None

If you wish to override this behavior, pass in: filter_on_sortable_fk=False:

    your_instance.get_next(filter_on_sortable_fk=False)

You may also pass in additional ORM "filer_args" as a list, or "filter_kwargs" as a dictionary, should you need to:

    your_instance.get_next(
        filter_args=[Q(field1=True) | Q(field2=True)],
        filter_kwargs={'title__icontains': 'blue'}
    )

Deprecation Warning

Previously "filter_kwargs" was named "extra_filters". With the addition of "filter_args", "extra_filters" was renamed for consistency.

Adding Sorting to an existing model

Django 1.5.x to 1.6.x

If you're adding Sorting to an existing model, it is recommended that you use django-south to create a schema migration to add the "order" field to your model. You will also need to create a data migration in order to add the appropriate values for the "order" column.

Example assuming a model named "Category":

def forwards(self, orm):
    for index, category in enumerate(orm.Category.objects.all()):
        category.order = index + 1
        category.save()

See: this link for more information on South Data Migrations.

Django 1.7.x or higher

Since schema migrations are built into Django 1.7, you don't have to use south, but the process of adding and running migrations is nearly identical. Take a look at the Migrations documentation to get started.

Django Admin Integration

To enable sorting in the admin, you need to inherit from SortableAdmin:

from django.contrib import admin
from myapp.models import MySortableClass
from adminsortable.admin import SortableAdmin

class MySortableAdminClass(SortableAdmin):
    """Any admin options you need go here"""

admin.site.register(MySortableClass, MySortableAdminClass)

To enable sorting on TabularInline models, you need to inherit from SortableTabularInline:

from adminsortable.admin import SortableTabularInline

class MySortableTabularInline(SortableTabularInline):
    """Your inline options go here"""

To enable sorting on StackedInline models, you need to inherit from SortableStackedInline:

from adminsortable.admin import SortableStackedInline

class MySortableStackedInline(SortableStackedInline):
   """Your inline options go here"""

There are also generic equivalents that you can inherit from:

from adminsortable.admin import (SortableGenericTabularInline,
    SortableGenericStackedInline)
    """Your generic inline options go here"""

If your parent model is not sortable, but has child inlines that are, your parent model needs to inherit from NonSortableParentAdmin:

from adminsortable.admin import (NonSortableParentAdmin,
    SortableTabularInline)

class ChildTabularInline(SortableTabularInline):
    model = YourModel

class ParentAdmin(NonSortableParentAdmin):
    inlines = [ChildTabularInline]

Overriding queryset()

django-admin-sortable supports custom queryset overrides on admin models and inline models in Django admin!

If you're providing an override of a SortableAdmin or Sortable inline model, you don't need to do anything extra. django-admin-sortable will automatically honor your queryset.

Have a look at the WidgetAdmin class in the sample project for an example of an admin class with a custom queryset() override.

Overriding queryset() for an inline model

This is a special case, which requires a few lines of extra code to properly determine the sortability of your model. Example:

# add this import to your admin.py
from adminsortable.utils import get_is_sortable


class ComponentInline(SortableStackedInline):
    model = Component

    def queryset(self, request):
        qs = super(ComponentInline, self).queryset(request).filter(
            title__icontains='foo')

        # You'll need to add these lines to determine if your model
        # is sortable once we hit the change_form() for the parent model.

        if get_is_sortable(qs):
            self.model.is_sortable = True
        else:
            self.model.is_sortable = False
        return qs

If you override the queryset of an inline, the number of objects present may change, and adminsortable won't be able to automatically determine if the inline model is sortable from here, which is why we have to set the is_sortable property of the model in this method.

Sorting subsets of objects

It is also possible to sort a subset of objects in your model by adding a sorting_filters tuple. This works exactly the same as .filter() on a QuerySet, and is applied after get_queryset() on the admin class, allowing you to override the queryset as you would normally in admin but apply additional filters for sorting. The text "Change Order of" will appear before each filter in the Change List template, and the filter groups are displayed from left to right in the order listed. If no sorting_filters are specified, the text "Change Order" will be displayed for the link.

Self-Referential SortableForeignKey

You can specify a self-referential SortableForeignKey field, however the admin interface will currently show a model that is a grandchild at the same level as a child. I'm working to resolve this issue.

⚠️ Important!

django-admin-sortable 1.6.6 introduced a backwards-incompatible change for sorting_filters. Previously this attribute was defined as a dictionary, so you'll need to change your values over to the new tuple-based format.

An example of sorting subsets would be a "Board of Directors". In this use case, you have a list of "People" objects. Some of these people are on the Board of Directors and some not, and you need to sort them independently.

class Person(Sortable):
    class Meta(Sortable.Meta):
        verbose_name_plural = 'People'

    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    is_board_member = models.BooleanField('Board Member', default=False)

    sorting_filters = (
        ('Board Members', {'is_board_member': True}),
        ('Non-Board Members', {'is_board_member': False}),
    )

    def __unicode__(self):
        return '{} {}'.format(self.first_name, self.last_name)

Extending custom templates

By default, adminsortable's change form and change list views inherit from Django admin's standard templates. Sometimes you need to have a custom change form or change list, but also need adminsortable's CSS and JavaScript for inline models that are sortable for example.

SortableAdmin has two attributes you can override for this use case:

change_form_template_extends
change_list_template_extends

These attributes have default values of:

change_form_template_extends = 'admin/change_form.html'
change_list_template_extends = 'admin/change_list.html'

If you need to extend the inline change form templates, you'll need to select the right one, depending on your version of Django. For 1.10.x or below, you'll need to extend one of the following:

templates/adminsortable/edit_inline/stacked-1.10.x.html
templates/adminsortable/edit_inline/tabular-inline-1.10.x.html

otherwise, extend:

templates/adminsortable/edit_inline/stacked.html
templates/adminsortable/edit_inline/tabular.html

A Special Note About Stacked Inlines...

The height of a stacked inline model can dynamically increase, which can make them difficult to sort. If you anticipate the height of a stacked inline is going to be very tall, I would suggest using SortableTabularInline instead.

Custom JS callbacks after sorting is complete

If you need to define a custom event or other callback to be executed after sorting is completed, you'll need to:

  1. Create a custom template for to add your JavaScript
  2. Populate the after_sorting_js_callback_name on your model admin

An example of this can be found in the "samples" application in the source. Here's a model admin for a model called "Project":

class ProjectAdmin(SortableAdmin):
    inlines = [
        CreditInline, NoteInline, GenericNoteInline,
        NonSortableCreditInline, NonSortableNoteInline
    ]
    list_display = ['__str__', 'category']

    after_sorting_js_callback_name = 'afterSortCallback'  # do not include () - just function name
    sortable_change_list_template = 'adminsortable/custom_change_list.html'
    sortable_change_form_template = "adminsortable/custom_change_form.html"

This example is going to add a custom callback on the parent model, and it's inlines. Here is the JavaScript added to the custom change list:

{% extends 'adminsortable/change_list.html' %}

{% block extrahead %}
  {{ block.super }}

  <script>
    django.jQuery(document).on('order:changed', function(event) {
      console.log(event.message);
      // your code here
    });

    window['{{ after_sorting_js_callback_name }}'] = function() {
      django.jQuery(document).trigger({ type: 'order:changed', message: 'Order changed', time: new Date() });
    };
  </script>
{% endblock %}

and the custom change form, for the inline models:

{% extends "adminsortable/change_form.html" %}

{% block extrahead %}
  {{ block.super }}

  <script>
    django.jQuery(document).on('order:changed', function(event) {
      console.log(event.message);
      // your code here
    });

    window['{{ after_sorting_js_callback_name }}'] = function() {
      django.jQuery(document).trigger({ type: 'order:changed', message: 'Order changed', time: new Date() });
    };
  </script>
{% endblock %}

Ideally, you'd pull in a shared piece of code for your callback to keep your code DRY.

Django-CMS integration

Django-CMS plugins use their own change form, and thus won't automatically include the necessary JavaScript for django-admin-sortable to work. Fortunately, this is easy to resolve, as the CMSPlugin class allows a change form template to be specified:

# example plugin
from cms.plugin_base import CMSPluginBase

class CMSCarouselPlugin(CMSPluginBase):
    admin_preview = False
    change_form_template = 'cms/sortable-stacked-inline-change-form.html'
    inlines = [SlideInline]
    model = Carousel
    name = _('Carousel')
    render_template = 'carousels/carousel.html'

    def render(self, context, instance, placeholder):
        context.update({
            'carousel': instance,
            'placeholder': placeholder
        })
        return context

plugin_pool.register_plugin(CMSCarouselPlugin)

The contents of sortable-stacked-inline-change-form.html at a minimum need to extend the extrahead block with:

{% extends "admin/cms/page/plugin_change_form.html" %}
{% load static from staticfiles %}

{% block extrahead %}
    {{ block.super }}
    <script src="{% static 'adminsortable/js/jquery-ui-django-admin.min.js' %}"></script>
    <script src="{% static 'adminsortable/js/jquery.ui.touch-punch.min.js' %}"></script>
    <script src="{% static 'adminsortable/js/jquery.django-csrf.js' %}"></script>
    <script src="{% static 'adminsortable/js/admin.sortable.stacked.inlines.js' %}"></script>

    <link rel="stylesheet" type="text/css" href="{% static 'adminsortable/css/admin.sortable.inline.css' %}" />
{% endblock extrahead %}

Sorting within Django-CMS is really only feasible for inline models of a plugin as Django-CMS already includes sorting for plugin instances. For tabular inlines, just substitute:

<script src="{% static 'adminsortable/js/admin.sortable.stacked.inlines.js' %}"></script>

with:

<script src="{% static 'adminsortable/js/admin.sortable.tabular.inlines.js' %}"></script>

Notes

From django-cms 3.x the path of change_form.html has changed. Replace the follwing line:

{% extends "admin/cms/page/plugin_change_form.html" %}

with

{% extends "admin/cms/page/plugin/change_form.html" %}

From django-admin-sortable 2.0.13 the jquery.django-csrf.js was removed and you have to include the snippet-template. Change the following line:

<script type="text/javascript" src="{% static 'adminsortable/js/jquery.django-csrf.js' %}"></script>

to

{% include 'adminsortable/csrf/jquery.django-csrf.html' with csrf_cookie_name='csrftoken' %}

Please note, if you change the CSRF_COOKIE_NAME you have to adjust csrf_cookie_name='YOUR_CSRF_COOKIE_NAME'

Rationale

Other projects have added drag-and-drop ordering to the ChangeList view, however this introduces a couple of problems...

  • The ChangeList view supports pagination, which makes drag-and-drop ordering across pages impossible.
  • The ChangeList view by default, does not order records based on a foreign key, nor distinguish between rows that are associated with a foreign key. This makes ordering the records grouped by a foreign key impossible.
  • The ChangeList supports in-line editing, and adding drag-and-drop ordering on top of that just seemed a little much in my opinion.

Status

django-admin-sortable is currently used in production.

What's new in 2.3.0?

  • Django 4 compatibility

Future

  • Better template support for foreign keys that are self referential. If someone would like to take on rendering recursive sortables, that would be super.

License

django-admin-sortable is released under the Apache Public License v2.

django-admin-sortable's People

Contributors

alsoicode avatar iambrandontaylor avatar jaap3 avatar blag avatar vstoykov avatar dokterbob avatar alesasnouski avatar flimm avatar matt-leach avatar gladson avatar genisysram avatar sushifan avatar timur-orudzhov avatar mark-ignacio avatar shjohnson-pi avatar serhiyromanov avatar sh-cho avatar michael-k avatar ionelmc avatar ekinertac avatar camilonova avatar foonicorn avatar adampeacock-rectory avatar alex-sichkar avatar marcelometal avatar itbabu avatar avoine avatar peterisb avatar rfleschenberg avatar sethwoodworth avatar

Stargazers

Park Hee Chan avatar Radomirs Cirskis avatar Sky Guy avatar Saúl Hormazábal avatar  avatar Đạt Phạm avatar Li Xulun avatar Rajendra Agrawal avatar Fedor Arbuzov avatar Phong Tran avatar Diego Muñoz avatar Doscript avatar Alexander Price avatar Sean P. Myrick V19.1.7.2 avatar Jarkko Saltiola avatar Anton Kurashev avatar Almas Baktubayev avatar Christopher Carvalho avatar Katherine "Kati" Michel avatar Amir Mahmoodi(Khalife) avatar Ariel Roffé avatar Artem Samoilov avatar Aron avatar sosojustdo avatar Erkan Demiralay avatar Jesse Panganiban avatar Mohamed Meftouh avatar Sun RA avatar 毛人脸 avatar Chieh Teng Chang avatar Daniel Różycki avatar Rik avatar Gutierri Barboza avatar Michael Santelia avatar Sepideh Hosseinian avatar Nima Parsa avatar Matthew Grant  avatar adonis simo avatar Mohammad Mahdi Mohajer avatar Reza Rohani avatar Shan Tharanga avatar Mohamad Jahani avatar Hakan Özdemir avatar Mogra avatar Shepard Geng avatar Precious Imoniakemu avatar Jinghao Hu avatar  avatar  avatar Khoi Nguyen Tinh Song avatar Uzzal Hossain avatar Daniel avatar Krittin Khanueng avatar Fabien BERNARD avatar zlh avatar Joris avatar Zach Kanzler avatar Rafał Gawlik avatar Aleksandr Usolcev avatar Filip Todic avatar Nabin Dahal avatar  avatar Hussaini Usman avatar mrFoggg avatar Ahmet Yusuf Başaran avatar  avatar Alexey Petukhov avatar Moussier Cissé avatar  avatar  avatar NRR avatar Goto Hayato avatar  avatar Adrian Likins avatar  avatar SP avatar Patrick Curl avatar Nasir Hussain avatar Pavel Sukhanov avatar Steven Albarracin avatar  avatar Prince Letsyo avatar Youssef Hammoud avatar i_82 avatar Aakash Singh avatar Rodrigo Eiti Kimura avatar Al Mahdi avatar Prince Carl Velasco avatar Yutaro Fujikawa avatar Stephen G Tuggy avatar Michael Chrisco avatar Oliver (Chia-Hong) Chou avatar Thiago Lara avatar Mario Medina Hernández  avatar Christopher Maile avatar Palak Shivlani avatar Ali Kasimoglu avatar Aryaman avatar Harald Nezbeda avatar Ram avatar

Watchers

Noam  V avatar  avatar Dariush Azimi avatar James Cloos avatar Jacob Rief avatar luismanolo avatar  avatar  avatar Andrea avatar Tom Zeng avatar kiwipi avatar  avatar  avatar  avatar Vladimir Myshkovski avatar  avatar Sean P. Myrick V19.1.7.2 avatar

django-admin-sortable's Issues

GenericTabularInline and GenericStackedInline?

hi
I'm trying to make GenericTabularInline and GenericStackedInline working with your app.

so i've brutally wrote these lines "black box" thinking ... (in django admin the template for GenericTabularInline and TabularInline is the same)

from django.contrib.contenttypes import generic

class SortableGenericTabularInline(SortableInlineBase, generic.GenericTabularInline):
    """Custom template that enables sorting for tabular inlines"""
    template = 'adminsortable/edit_inline/tabular.html'

class SortableGenericStackedInline(SortableInlineBase,  generic.GenericStackedInline):
    """Custom template that enables sorting for stacked inlines"""
    template = 'adminsortable/edit_inline/stacked.html'

But i've a TemplateSyntaxError:

Caught NoReverseMatch while rendering: Reverse for 'admin_do_sorting' with arguments '(54,)' and keyword arguments '{}' >not found.

the only thing that doesn't seems to work is this url:

          {% if inline_admin_form.original %}
          <input type="hidden" name="admin_sorting_url" value="{% url admin:admin_do_sorting inline_admin_form.original.model_type_id %}" />
          {% endif %}

any suggestions?
Now I am now looking into your admin views

'int' object has no attribute '_meta'

In template adminsortable\edit_inline\stacked.html, error at line 20

specifically in this line:

<input type="hidden" name="admin_sorting_url" value="{% get_do_sorting_url inline_admin_form.original.model_type_id %}" /> 

If in admin.py i use admin.StackedInline instead of SortableStackedInline it works but it's not sortble

models.py

class Slideshow(models.Model):
    title = models.CharField(_('title'), max_length=255)

    def __unicode__(self):
        return self.title

    class Meta:
        app_label = "Slideshow"
        db_table = "cmsplugin_nivoslider2_slideshow"


class SlideshowImage(Sortable):
    gallery = SortableForeignKey(Slideshow)
    image =  models.ImageField(upload_to="banners/%Y/%m/%d")
    link = models.URLField(null=True, blank=True)

    from django.core.files.base import ContentFile
    def save_file(request):
        mymodel = MyModel.objects.get(id=1)
        file_content = ContentFile(request.FILES['video'].read())
        mymodel.video.save(request.FILES['video'].name, file_content)

    class Meta(Sortable.Meta):
        app_label = "Slideshow"
        db_table = "cmsplugin_nivoslider2_slideshowimage"

admin.py

class SlideshowImageStackedInline(SortableStackedInline):
    model = SlideshowImage

class SlideshowAdmin(admin.ModelAdmin):
    inlines = [SlideshowImageStackedInline,]

admin.site.register(Slideshow, SlideshowAdmin)

Any help would be appreciated, thanks

Andrés

SortableInline not working

I copied the example from the readme file exactly but it still doesn't work.
In the browser the hand icon appears when I hover over the rows but moving them doesn't work.
There is also an error in the console:
Uncaught TypeError: undefined is not a function : admin.sortable.stacked.inlines.js:9

Can I make ManyToManyField?

models.py

class Project(SimpleModel, Sortable):
    class Meta(Sortable.Meta):
        pass
    category =  models.ManyToManyField(Category,  related_name='groups')
    description = models.TextField()

admin.py

# class CategoryInline(SortableTabularInline): # I tried this, but no luck
class CategoryInline(admin.TabularInline):
    model = Project.category.through 
class ProjectAdmin(SortableAdmin):
    inlines = [
    CategoryInline,
    CreditInline, 
    #NoteInline, 
    #GenericNoteInline
    ]
    #list_display = ['__unicode__', 'category']
    exclude = ('category',)

Is there any way I can create something like this?
untitled

MultiValueDictKeyError on Django 1.6 change form

Saving changes with sortable stacked admin inlines creates a MultiValueDictKeyError error in Django 1.6:

Models.py

# -*- coding: utf-8 -*-
from django.db import models
from django.utils.translation import ugettext_lazy as _
from backend import settings as bs
from adminsortable.models import Sortable

class Presentation(Sortable):
    title_de = models.CharField(max_length=200, verbose_name=_('German title'))
    preview_image = models.ImageField(upload_to='images', verbose_name=_('Preview image'))

    def __unicode__(self):
        return self.title_de

    class Meta(Sortable.Meta):
        pass

class Slide(models.Model):
    title = models.CharField(max_length=200, verbose_name=_('Title'))
    slide_type = models.CharField(max_length=50, choices=bs.SLIDE_TYPE_CHOICES, default=bs.SLIDE_TYPE_REQUIRED, verbose_name=_('Slide type'))
    image_de = models.ImageField(upload_to='images', verbose_name=_('German or default image'))

    def __unicode__(self):
        return self.title

class PresentationEntry(Sortable):
    presentation = models.ForeignKey('Presentation', related_name='entries')
    slide = models.ForeignKey('Slide', related_name='presentation_entries')

    class Meta(Sortable.Meta):
        pass

Admin.py

from django.contrib import admin
from adminsortable.admin import SortableAdmin, SortableStackedInline
from backend.models import Presentation, Slide, PresentationEntry

class PresentationEntryInline(SortableStackedInline):
    model = PresentationEntry
    extra = 0

class PresentationAdmin(SortableAdmin):
    inlines = [PresentationEntryInline]

admin.site.register(Presentation, PresentationAdmin)
admin.site.register(Slide)

Error

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin/backend/presentation/1/

Django Version: 1.6
Python Version: 2.7.5
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'backend',
 'imagekit',
 'rest_framework',
 'south',
 'adminsortable',
 'django.contrib.admin')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
  430.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  99.                     response = view_func(request, *args, **kwargs)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  52.         response = view_func(request, *args, **kwargs)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
  198.             return view(request, *args, **kwargs)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/adminsortable/admin.py" in change_view
  212.             extra_context=extra_context)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
  29.             return bound_func(*args, **kwargs)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  99.                     response = view_func(request, *args, **kwargs)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
  25.                 return func(self, *args2, **kwargs2)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/db/transaction.py" in inner
  339.                 return func(*args, **kwargs)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/contrib/admin/options.py" in change_view
  1227.             if all_valid(formsets) and form_validated:
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/forms/formsets.py" in all_valid
  415.         if not formset.is_valid():
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/forms/formsets.py" in is_valid
  292.         err = self.errors
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/forms/formsets.py" in errors
  267.             self.full_clean()
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/forms/formsets.py" in full_clean
  314.             form = self.forms[i]
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/utils/functional.py" in __get__
  49.         res = instance.__dict__[self.func.__name__] = self.func(instance)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/forms/formsets.py" in forms
  133.         forms = [self._construct_form(i) for i in xrange(self.total_form_count())]
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/forms/models.py" in _construct_form
  839.         form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs)
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/forms/models.py" in _construct_form
  555.             pk = self.data[pk_key]
File "/Users/moritz/python/presenation_app/lib/python2.7/site-packages/django/utils/datastructures.py" in __getitem__
  301.             raise MultiValueDictKeyError(repr(key))

Exception Type: MultiValueDictKeyError at /admin/backend/presentation/1/
Exception Value: "u'entries-0-id'"

Inlines in django CMS plugins/iframes

Inlines in django CMS plugins don't seem to be sortable. I don't really understand JS, but I think it is because a plugin in a placeholder opens its admin in an iframe. Having a look at that iframe, it seems to lack the <script type="text/javascript" src="/static/cms/js/libs/jquery.ui.sortable.js"></script> reference that the containing page has.

SortableInline breaks when "extra=0"

This works:

class QuestionsCollectionQuestionInline(SortableInline):
    model = QuestionsCollectionQuestion
    extra = 1

This dont:

class QuestionsCollectionQuestionInline(SortableInline):
    model = QuestionsCollectionQuestion
    extra = 0

Thanks for a great app!

Change order admin view resets order each time

This app is working great for me, except for one pretty large issue - each time I go to change the order of an object, the objects don't retain their sorting. This means I have to sort the entire collection each time I want to change something.

I've recorded a quick screencast showing the issue here: http://cl.ly/2l0a1u0E393C2W2k0O0O

This is occurring on both 1.0.9 and 1.2.

You're not correctly handling IndexError

https://github.com/btaylordesign/django-admin-sortable/blob/master/adminsortable/models.py#L45

The above code doesn't catch both TypeError and IndexError, it catches TypeError and assigns the exception to a variable named IndexError. To target more than one exception you need to explicitly group those exceptions with parenthesis

> python
Python 2.7.1 (r271:86832, Aug  5 2011, 03:30:24) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> try:
...     range(4)[6]
... except ValueError, IndexError:
...     print "it works"
... 
Traceback (most recent call last):
  File "<console>", line 2, in <module>
IndexError: list index out of range
>>> try:
...     range(4)[6]
... except (ValueError, IndexError):
...     print "it works"
... 
it works

Sortable many to many field

I don't see a sortable many-to-many field in the documentation.

I am already using this project for some foreign key fields and have a need for a sortable many-to-many field.

Would this be a desirable feature for this project?

Support sortable inlines while keeping parent immutable (a non sortable model)

In addition to the discussion in #30 this ticket arose. I added a patch as a quick fix. Downside, the inline's model has to be registered to the admin.

Index: adminsortable/admin.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- adminsortable/admin.py  (revision 279477da7ba1dbdf84e85d6d2f63910f88bf4b5e)
+++ adminsortable/admin.py  (revision )
@@ -221,6 +221,22 @@
             mimetype='application/json')


+class SortableInlinesAdmin(ModelAdmin):
+    """
+    Use this class to create sortable inlines while keeping the parent model unsortable.
+    Requires the inline model classes to be registered on the admin though.
+    """
+    # todo, there's better ways to achieve this
+
+    class Media:
+        js = (
+            '//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js',
+            '//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js',
+            'adminsortable/js/admin.sortable.stacked.inlines.js',
+            'adminsortable/js/admin.sortable.js'
+        )
+
+
 class SortableInlineBase(InlineModelAdmin):
     def __init__(self, *args, **kwargs):
         super(SortableInlineBase, self).__init__(*args, **kwargs)
Index: sample_project/app/admin.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- sample_project/app/admin.py (revision 279477da7ba1dbdf84e85d6d2f63910f88bf4b5e)
+++ sample_project/app/admin.py (revision )
@@ -1,8 +1,8 @@
 from django.contrib import admin

 from adminsortable.admin import (SortableAdmin, SortableTabularInline,
-    SortableStackedInline, SortableGenericStackedInline)
-from app.models import Category, Project, Credit, Note, GenericNote
+    SortableStackedInline, SortableGenericStackedInline, SortableInlinesAdmin)
+from app.models import Category, Project, Agenda, Credit, Note, GenericNote


 admin.site.register(Category, SortableAdmin)
@@ -27,3 +27,10 @@
     list_display = ['__unicode__', 'category']

 admin.site.register(Project, ProjectAdmin)
+
+
+class AgendaAdmin(SortableInlinesAdmin):
+    inlines = [GenericNoteInline]
+    list_display = ['__unicode__']
+
+admin.site.register(Agenda, AgendaAdmin)
Index: sample_project/app/models.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- sample_project/app/models.py    (revision 279477da7ba1dbdf84e85d6d2f63910f88bf4b5e)
+++ sample_project/app/models.py    (revision )
@@ -37,6 +37,14 @@
     description = models.TextField()


+#a model that is not sortable but can have inlines that are.
+class Agenda(SimpleModel):
+    class Meta:
+        pass
+
+    description = models.TextField()
+
+
 #registered as a tabular inline on `Project`
 class Credit(Sortable):
     class Meta(Sortable.Meta):
\ No newline at end of file

Incompatible with Django version 1.6

Dango has moved to version 1.9 of JQuery, this removed the $.browser object. The version of JQuery UI in admin-sortable seems to use the $.browser.msie object and so throws an error:

Uncaught TypeError: Cannot read property 'msie' of undefined

Add another button is missing with SortableTabularInline

A couple of issues using SortableTabularInline:
Add another button is missing.

There's always 1 more inline field than I set with the extra parameter. But anything entered into the 'bonus' field is discarded when saving. My workaround is to set extra to a high number but that's not ideal.

The width of select boxes (for ForeignKeys) can get ridiculously long and there doesn't seem to be any way to override that. My attempt to override with formfield_overrides didn't work.

Error in admin_do_sorting

Hello,
I am using django-admin-sortable with grappelli, i got the error as
"Reverse for 'admin_do_sorting' with arguments '(175L,)' and keyword arguments '{}' not found".

The error message shows that error in stacked.html file on below .

I follow all the steps, adminsortable will be created in static folder.
Can anybody help me solve this? why this error comes?

I can´t see sortable options anywhere

Hi, I added "adminsortable" to installed apps, and I can´t see any sortable options anywhere or drag&drop. I don´t know what I´m doing wrong. I´m using django 1.4 and I get no errors. I realized no javascript or css related to adminsortable is loaded. This is my model:

from django.db import models
from django.contrib import admin
from filebrowser.fields import FileBrowseField
from adminsortable.models import Sortable
from adminsortable.admin import SortableAdmin

class Work(Sortable):
    class Meta(Sortable.Meta):
        verbose_name_plural = 'Trabajos'

    title = models.CharField(max_length=255)
    image = FileBrowseField("Imagen destacada", max_length=255, blank=True, null=True)

    def __unicode__(self):
        return self.title

class WorkAdmin(SortableAdmin):
    list_display = ("__unicode__", "title", "image")

admin.site.register(Work, SortableAdmin)

I also tried with python admin.site.register(Work, WorkAdmin) but I still get nothing

Any ideas?

Example from the doc

The example from the doc doesn't work for me (if parent model isn't inherited from Sortable):

It is also possible to order objects relative to another object that is a ForeignKey, even if that model does not inherit from Sortable:
from adminsortable.fields import SortableForeignKey

#models.py
class Category(models.Model):
    title = models.CharField(max_length=50)
    ...

class Project(Sortable):
    class Meta(Sortable.Meta):
        pass

    category = SortableForeignKey(Category)
    title = models.CharField(max_length=50)

    def __unicode__(self):
        return self.title

Are you sure the code above should work?

Item highlighting after sorting is broken?

There are problems in "jquery-ui-django-admin.min.js".
I got js errors:
Uncaught TypeError: Cannot set property 'backgroundColor' of undefined
Uncaught TypeError: Object # has no method 'effect'

Ordering not working for Inline objects

Hello,
I installed d-a-s to deal with the following situation: I have blog posts which are composed by slots. Every post can have many slots. I need this slots to be sortable in the admin panel.

In the admin panel I can see my post and post slots but there is no drag and drop feature working. Jquery is included and I followed your instructions step by step. Any idea?

models.py

from adminsortable.models import Sortable
from adminsortable.fields import SortableForeignKey

class Post(models.Model):

    action = models.ForeignKey(Action)
    title = models.TextField(null=False, blank=False)
    slug = models.SlugField(null=False, blank=False)
    created_at = models.DateTimeField(null=False, blank=False)
    description = models.TextField(null=True, blank=True)
    published = models.BooleanField()

    def __unicode__(self):
        return "Action: {obj.action}, Title: {obj.title}".format(obj=self)


class PostSlot(Sortable):

    class Meta(Sortable.Meta):
        pass

    CONTENT_TYPE = Choices(
        ('0', 'text', _('Text')),
        ('1', 'html', _('Html')),
    )

    post =SortableForeignKey(Post)
    content = HTMLField()
    content_type = models.CharField(choices=CONTENT_TYPE, max_length=1, default=CONTENT_TYPE.text)

    def __unicode__(self):
        return "Post: {obj.post.title}, Content: {obj.content}".format(obj=self)

admin.py

from adminsortable.admin import SortableTabularInline,SortableStackedInline, SortableAdmin

class PostSlotInline(SortableStackedInline):
    model = PostSlot



class PostAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('title',), }
    inlines = [
        PostSlotInline,
    ]

admin.site.register(Post, PostAdmin)

Incompatibility with Django 1.5: url syntax changed

I have installed and configured the plugin. I also added the schema- and data-migration with South. But when i click on "change order" in the admin i get the following error:

"The syntax of 'url' changed in Django 1.5, see the docs."

Here is the detailed message (Line 6 is the problem):

TemplateSyntaxError
Could not parse the remainder: ':admin_do_sorting' from 'admin:admin_do_sorting'. The syntax of 'url' changed in Django 1.5, see the docs.

1   {% load adminsortable_tags %}
2   
3   <form>
4       <input name="pk" type="hidden" value="{{ object.pk }}" />
5   </form>
6   <a href="{% url admin:admin_do_sorting object.model_type_id %}" class="admin_sorting_url">{{ object }}</a>
7   

Ordering page restyle

Hi there.
I'm using this great app. Thanks for it.
Was just wondering are you happy with current look of it on the "Change order" page?
I'm basically not and would love to change it, and can do it.
Would you be interested in that? Just so that the ordering page would look a bit more.. humane?

Unable to sort in more than one project application.

Hi !
Changed sample project , added myapp application which is a slightly changed copy of app application. Go to change object page in both app and compare links in li elements : they are the same.

So admin_do_sorting url doesn't take in consideration application name - it will be the same for ALL applications!

See alesasnouski@1c2964c

Problem with non-ascii characters

Traceback:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response

  1.                     response = callback(request, _callback_args, *_callback_kwargs)
    
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  2.                 response = view_func(request, _args, *_kwargs)
    
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  3.     response = view_func(request, _args, *_kwargs)
    
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
  4.         return view(request, _args, *_kwargs)
    
    File "/tmp/django-admin-sortable/adminsortable/admin.py" in sort_view
  5.             capfirst(verbose_name_plural)),
    

Exception Type: UnicodeEncodeError at /admin/app/category/sort/
Exception Value: 'ascii' codec can't encode characters in position 0-8: ordinal not in range(128)

For fix it, change str to unicode. That fixes:

'title': u'Drag and drop {0} to change display order'.format(
capfirst(verbose_name_plural)),

icon_calendar.gif and icon_clock.gif urls built out of order

When using Amazon S3 storage, boto, and django-storages the urls are built with the file name after the added amazon expiry/key/etc information.

https://bucket.s3.amazonaws.com/admin?Signature=[removed]&Expires=[removed]&AWSAccessKeyId=[removed]img/icon_clock.gif

They should look like this.

https://bucket.s3.amazonaws.com/admin/img/icon_clock.gif?Signature=[removed]&Expires=[removed]&AWSAccessKeyId=[removed]

I looked at django-admin-sortable code and found it is re-initializing with javascript, but I'm not sure specifically how/why/what it is doing so I'm a little unsure how to fix this. If you have any suggestions I would be happy to fix it and submit a pull request.

Thank you.

'str' object has no attribute 'render_js'

Hi,
I've installed this into mezzanine. It works great with StackedInline but when I'm trying to sort a table I get the following error:

Error during template rendering
In template /usr/lib/python2.6/site-packages/grappelli_safe/templates/admin/change_list.html, error at line 21
'str' object has no attribute 'render_js'


11          #changelist table thead th:first-child {width: inherit}
12      </style>
13      {% endif %}
14  {% endblock %}
15  
16  <!-- JAVASCRIPTS -->
17  {% block javascripts %}
18      {% url "admin:jsi18n" as jsi18nurl %}
19      <script type="text/javascript" src="{{ jsi18nurl|default:"../../jsi18n/" }}">          </script>
20      {{ block.super }}
21      {{ media|use_grappelli_media }}
22      <script type="text/javascript" src="{% admin_media_prefix     %}js/admin/Changelist.js"></script>
23      {% if is_popup %}
24      <script type="text/javascript">
25          // HACK: REMOVE ACTIONS and LIST_EDITABLES FOR POPUPS
26          $('div.actions').hide();
27          $('p.submit-row').hide();
28          $('input.action-select').parent().hide();
29          $('input#action-toggle').parent().hide();
30      </script>
31      {% endif %}

Any ideas on how to fix this ?

Regards.

Can't disable JQuery in javascript_includes.html

There is not way to disable jquery shipped in javascript_includes.html template.

JQuery is used almost in every project. It can be used by custom fields in admin interface. Second JQuery may overwrite the namespace of the first one and create promlems.

IMHO it's better to include JQuery in admin media and provide a way not to include JQuery in the template.

Inline Only Sort

In working with adminsortable for a current project I came across a point that may need clarification in the docs. I have two models...GalleryAlbum and GalleryImage. GalleryImage holds a foreign key to GalleryAlbum. In the admin GalleryImage is a TabularInline of GalleryAlbum.

In order to get SortableTabularInline working for GalleryImage I also had to add SortableAdmin to the GalleryAlbum.

class GalleryImageInline(SortableTabularInline):
    model = GalleryImage

class GalleryAlbumAdmin(SortableAdmin):
    raw_id_fields = ('article', )
    inlines = [GalleryImageInline]
    save_on_top = True

admin.site.register(GalleryAlbum, GalleryAlbumAdmin)

The issue I'm unclear on is that I don't need/want the GalleryAlbumAdmin to be sortable...only the GalleryImage Inline within each GalleryAlbum. I attempted to overwrite the change_list.html template to remove the extra button on GalleryAlbum but couldn't get it.

Certainly not a deal breaker but curious if you had any ideas?

Thanks for all your work on this, Brandon. Great project that is easy to implement.

Problem 'admin_do_sorting'

Hi
I have a problem usin sortable:
Reverse for 'admin_do_sorting' with arguments '(45,)' and keyword arguments '{}' not found. 0 pattern(s) tried: []

I saw someone here with the same problem but didn't see how fix it

I'm really new in django.
Could you help me ?

How to proceed with an existing order field

Hello, I have a bunch of models using a custom "order" field and I'd like to start using django-admin-sortable, what's the best approach? The README deals with existing models with no order field, but what about existing models with an existing order field?

My field is simply: order = models.IntegerField(default=0) and it's valued by the user in the admin.

Any ideas? Shall I rename this field, inherit from Sortable and copy the existing values over with a migration or is there a better approach?

Template Syntax Error: Invalid template name in 'extends' tag

Hello,
I have a model that extends the Sortable model and the admin extends SortableAdmin

Everything works as intended about half the time, but other times I get this error with the admin sortable template when I click to add a new sortable object or edit an existing object:

Invalid template name in 'extends' tag: ''. Got this from the 'change_form_template_extends' variable

1 {% extends change_form_template_extends %}
2 {% load i18n admin_modify %}
3 {% load url from future %}
4
5 {% block extrahead %}
6 {{ block.super }}
7 {% url 'admin:jsi18n' as jsi18nurl %}
8
9 {% if has_sortable_tabular_inlines or has_sortable_stacked_inlines %}
10 {% include sortable_javascript_includes_template with inlines=True %}
11 {% endif %}

I'm not sure why it's happening but I can replicate it consistently from the change list page if I click on 'change order', then go back to the change list page and try to add or edit an existing model object. However it does occur even without messing with the change order button

This issue occurs on Django 1.5.1 with django-admin-sortable 1.4.9

SortableStackedInline diables checking of "Delete" checkbox on the inline.

Django==1.5
django-admin-sortable==1.4.6

from adminsortable.admin import SortableAdmin, SortableStackedInline

class QualificationInline(SortableStackedInline):
model = Qualification
extra = 1

class StaffAdmin(SortableAdmin):
inlines = [QualificationInline]

admin.site.register(Staff, StaffAdmin)

screen shot 2013-05-04 at 12 10 53

adminsortable.admin.SortableAdmin ignores self.queryset

SortableAdmin queries using self.model.objects, however it should be using self.queryset(request) to retrieve the queryset from the admin.

Not doing this violates the ModelAdmin pattern which expects that the queryset can be filtered on request, or whatever else the developer may be doing in an overridden ModelAdmin.queryset.

This has been Django's default behavior since Django 1.1 so it should be safe to rely on this:

https://docs.djangoproject.com/en/1.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.queryset

I can provide a pull request to resolve this issue, if desired.

reverse for 'myapp_mymodel_change' not found 0 patterns tried django 1.6

I am working on upgrading from django 1.5 to 1.6 and am currently hitting problems that appear to be related to django-admin-sortable.

Reverse for 'myapp_mymodel_change' with arguments '(5L,)' and keyword arguments '{}' not found. 0 pattern(s) tried: []

Originating at the template

...../python2.7/site-packages/adminsortable/templates/adminsortable/edit_inline/tabular.html

Is there something more I have to do to successfully get admin-sortable to work under 1.6 or am I missing something else outside of admin-sortable?

Thanks.

Sorting isn't available on SortableAdmin until I create a new object

Hi,

Firstly, great project! Thanks for working on it and providing it to the community!

I'm using Django 1.4.1 on Python2.7. I've implemented your instructions as accurately as possible and the end result is that it works!... well, sort of.

SortableAdmins work great, but only after I first create a new object/row (which I can then delete). The weirdest thing is, if I restart the server, I lose the ability to sort until again, I create a new object/row. The SortableForeignKey feature also works well, once I trigger it all to start working as above.

Unfortunately, SortableTabularAdmins and SortableStackedAdmins just aren't working at all. I cannot seem to get any gadgets for sorting to appear, even if I do create a new object/row.

Here's my models.py:

import os
from django.db import models
from adminsortable.fields import SortableForeignKey
from adminsortable.models import Sortable

class Category(Sortable):
        class Meta(Sortable.Meta):
                verbose_name_plural = "Categories"

        name        = models.CharField(max_length=64, unique=True)

        def __unicode__(self):
                return self.name


class Solution(Sortable):
        class Meta(Sortable.Meta):
                pass

        name        = models.CharField(max_length=64, unique=True)
        slug        = models.SlugField(blank=True)
        category    = SortableForeignKey('Category', related_name='solutions')
        description = models.TextField('Solution Description', blank=True, default='')

        def __unicode__(self):
                return self.name
...

And here's my admin.py

rom django.contrib import admin
from adminsortable.admin import SortableAdmin, SortableTabularInline, SortableStackedInline
from apps.saffron8.models import Person, Category, Solution, Piece, Image, Testimonial, Banner

class SolutionInline(SortableTabularInline):
        model = Solution
        exclude = ('description', )
        extra = 1
        prepopulated_fields = {'slug': ('name',)}

class CategoryAdmin(SortableAdmin):
        list_display  = ('name', )
        search_fields = ['name']
        inlines       = (SolutionInline, )

admin.site.register(Category, CategoryAdmin)


class SolutionAdmin(SortableAdmin):
        list_display        = ('name', 'category',)
        search_fields       = ['name', 'description',]
        prepopulated_fields = {'slug': ('name',)}

admin.site.register(Solution, SolutionAdmin)
...

I have checked my browser's (Chrome's) console and there are no JS errors at any time that I have found, if this helps.

Note: In case you're wondering, once I get this working, I will turn off admin for Solutions directly as I prefer them to be inlines to the Categories. I had it that way originally and I've only added SolutionAdmin because I can't seem to get the SolutionInline to work.

What have I missed?

Sorting relative to a parent that is not sortable gives an error

I don't want to work with inlines, as they tend to get too big. Therefore I defined two separate admins: a non-sortable Report admin and a sortable Chapter admin which should sort relative to the parent Report object.

When I try to change the order of the Chapter model by clicking on the 'Change Order' button on the top right of the Chapter admin page, the following error message is triggered:

NoReverseMatch at /admin/reporting/chapter/sort/
Reverse for 'admin_do_sorting' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'admin/reporting/chapter/sorting/do-sorting/(?P<model_type_id>\\d+)/$']

My models.py:

from adminsortable.models import Sortable
from adminsortable.fields import SortableForeignKey
...

class Report(models.Model):
  name = models.CharField(_('name'), max_length=200)

  class Meta:
    verbose_name = _('report')
    verbose_name_plural = _('reports')

class Chapter(Sortable):
  report = SortableForeignKey(Report, verbose_name=_('report'))
  name = models.CharField(_('name'), max_length=200)

  class Meta(Sortable.Meta):
    verbose_name = _('chapter')
    verbose_name_plural = _('chapters')

My admin.py:

from adminsortable.admin import NonSortableParentAdmin, SortableAdmin
...

class ChapterAdmin(SortableAdmin):
  raw_id_fields = ('report',)

class ReportAdmin(NonSortableParentAdmin):
  pass

admin.site.register(Chapter, ChapterAdmin)
admin.site.register(Report, ReportAdmin)

So right now it seems that I am unable to sort chapters within a report, unless I make the Report model Sortable (but this is not desired). Could you help me?

Clarify sorting foreign key objects

According to the docs, this is how you apply sortable to the 'many' end of a one-to-many relationship:

from adminsortable.fields import SortableForeignKey

#models.py
class Category(models.Model):
    title = models.CharField(max_length=50)
    ...

class Project(Sortable):
    class Meta(Sortable.Meta):
        pass

    category = SortableForeignKey(Category)
    title = models.CharField(max_length=50)

    def __unicode__(self):
        return self.title

What this doesn't mention, is because the Category ModelAdmin has to be Sortable, the Category model has to have an order field, otherwise an error is thrown.

adminsortable/change_form.html references non-existent javascript file

Hi there

Thanks for the great work.
I noticed while running the sample that the adminsortable/templates/adminsortable/change_form.html template references the adminsortable/js/jquery-ui.js file in line 11.
That file is however not present in adminsortable/static/adminsortable/js

Am I doing something wrong?

Thank you and greetings
Moritz

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.