jstree в джанговской админке

Итак у нас есть некая модель, данные которой представляют собой дерево. Соседние элементы мы сортируем вручную по полю position.


class MyModel(models.Model):
    parent = models.ForeignKey('self', verbose_name=u'Родительский элемент', \
        null=True, blank=True, related_name='children')
    name = models.CharField(u'Раздел', max_lengtch=255)
    position = PositiveSmallIntegerField(u'Позиция',  default=0)
    class Meta:
        ordering = ('position',)

Хочется чтобы в админке вместо списка объектов было дерево, при перетаскивании элемента автоматически изменялся parent и изменялись значения position.

Я использовал для этого замечательный jstree, а всю интеграцию с ним сделал яваскриптом, не трогая шаблон админки.

Для этого мы делаем в admin.py соотв. приложения такую запись:

class MyModelAdmin(admin.ModelAdmin):
    ordering = ('position',)
    list_display = ('pk','name','parent','position')
    raw_id_fields =('parent',)
    list_per_page = 900 #выводим все объекты одной страницей
    list_editable = ('name','position','parent')

    def parent_id(self,obj):
        return obj.parent and obj.parent.id or '0'

    class Meta:
        model = MyModel
    class Media:
        js = ('/static/js/jquery-1.3.2.min.js',
              '/static/lib/jquery.tree.min.js',
              '/static/lib/plugins/jquery.tree.contextmenu.js',
              '/static/js/mymodel_admin.js',)
        css = {
            'all':('/static/css/nestedsortablewidget.css',)
        }

Вместо /static конечно лучше использовать settings.MEDIA_URL

А вот сам скрипт mymodel_admin.js, который всё делает..

Для изменения parent,position и name(там можно переименовывать элементы) используется обычная джанговская форма для list_editable(мы её просто прячем)

Вот как это всё выглядит:

Add post to:   Delicious Reddit Slashdot Digg Technorati Google
Make comment

Pingbacks

15.04.2010 22:22 Отображение древовидных данных в админке. @softwaremaniacs.org
На форуме нашёл такой топик и далее ссылку на http://tabed.org/blog/2010/01/06/jstree-in-django-admin/ Неплохой вариант. А есть ли что-то оформленное в виде django приложения?

Comments

Спасибо за пост! Но у меня почему-то не работает.

Дерево красиво выводит, даже перемещает, но не сохраняет.

Выдает ошибки в консоли: continue must be inside loop [Break on this error] continue; // Skip to next token\n

document.getElementsBySelector is not a function [Break on this error] var changelistTable = document…tsBySelector(‘#changelist table’)[0];

document.forms[0][“form-” + $(NODE).attr(“alt”) + “-parent”] is undefined [Break on this error] document.forms[0][…EE_OBJ.parent(NODE).attr(‘pk’) : ”);

Еще в строке 120 надо добавить последний слэш, иначе неправильная ссылка.

И что за файл nestedsortablewidget.css? Откуда его взять и нужен ли он?

насчет слэша — может дело в параметре APPEND_SLASH в settings.py у меня он там был выставлен в true. Вообще посмотрите firebug`ом на саму форму, она скрыта и что выводит в javascript console команда buildtree(”)

а, стоп. Первые две ошибки к делу не относятся. Они из grappelli. По теме только третья:

document.forms[0][“form-” + $(NODE).attr(“alt”) + “-parent”] is undefined [Break on this error] document.forms[0][…EE_OBJ.parent(NODE).attr(‘pk’) : ”);

строка 103

у вас есть атрибут name у модели? или колонка по-другому называется? Вот эта немного подправленная версия, там можно изменить вверху имя этой колонки. http://www.djangosnippets.org/snippets/1858/

потом grappeli мог добавить ещё какие-то формы на страницу, там другие шаблоны, есть большая вероятность что под него надо менять многое.

поменял: document.forms[0][‘form-‘ + $(NODE).attr(‘alt’) + ‘-parent’].value = ((TREE_OBJ.parent(NODE) != -1) ? TREE_OBJ.parent(NODE).attr(‘pk’) : ”);

на: $(‘#id_form-‘ + $(NODE).attr(‘alt’) + ‘-parent’).value = ((TREE_OBJ.parent(NODE) != -1) ? TREE_OBJ.parent(NODE).attr(‘pk’) : ”);

ну и в других местах аналогично. Ошибка перестала возникать. Но сохранение все равно не происходит :(

попробуй создать простой пустой проект и поэксперементировать на нем. если всё будет работать-ищи отличия из-за которых не работает)

сделал все как написано, но дерево не начало строится.в чем может быть проблема?

сделал все как написано, но дерево не начало строится.в чем может быть проблема?