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(мы её просто прячем)
Вот как это всё выглядит:






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’) : ”);
ну и в других местах аналогично. Ошибка перестала возникать. Но сохранение все равно не происходит :(
попробуй создать простой пустой проект и поэксперементировать на нем. если всё будет работать-ищи отличия из-за которых не работает)
сделал все как написано, но дерево не начало строится.в чем может быть проблема?
сделал все как написано, но дерево не начало строится.в чем может быть проблема?