我正在使用FeinCMS TreeEditor接口为Django-Mptt树结构创建一个管理面板。此接口为每个节点提供一个“操作列”,用于快速添加或移动节点,而无需使用典型的Django管理操作选择框。
我想要做的是向此集合添加一个自定义管理操作,该操作将节点的pk传递给芹菜任务,然后该任务将添加一组节点作为子节点。现有的函数只是指向该任务的URL的href链接(添加/删除/移动),所以到目前为止我只是模仿了这个。
我的解决方案目前涉及:
当然必须有比这更好的方法吗?它有效,但感觉非常复杂和不干,我相信它会以奇怪的方式打破。
不幸的是,我只用了一两个月就开始使用Django了,所以我可能会使用一些明显的功能。我怀疑我可能能够使用get_urls()并直接在ModelAdmin中定义函数,或者使用注入的HTML中的代码块来直接调用函数,尽管我不确定它是如何以及是否被认为是更好的选项。
代码: 我已将所有内容重命名为更简单的库<>预订示例以从上面的示例图像中删除不相关的功能。
models.py
class Library(models.Model):
def get_books(self):
# Celery task; file omitted for brevity
get_books_in_library.delay(self.pk)
views.py
def get_books_in_library(request, library_id):
this_library = Library.objects.get(pk=library_id)
this_library.get_books_in_library()
messages.add_message(request, messages.SUCCESS, 'Library "{0}" books requested.'.format(this_library.name))
redirect_url = urlresolvers.reverse('admin:myapp_library_changelist')
return HttpResponseRedirect(redirect_url)
urls.py
urlpatterns = [
url(r'^admin/myapp/library/(?P<library_id>[0-9]+)/get_books/$', get_books_in_library, name='get books in library'),
url(r'^admin/', include(admin.site.urls)),
]
admin.py
class LibraryAdmin(TreeEditor):
model = Library
def _actions_column(self, obj):
actions = super(LibraryAdmin, self)._actions_column(obj)
actions.insert(
0, u'<a title="{0}" href="{1}/get_books"><img src="{2}admin/img/icon_addlink.gif" alt="{0}" /></a>'.format(
_('Get Books'),
obj.pk,
settings.STATIC_URL
)
)
return actions
请注意,如果您尝试执行此代码,我可能已经破坏了重命名并删除了无关紧要的内容,我认为它应该充分说明我在这里尝试做的事情。
答案 0 :(得分:0)
在今天挖掘并简单地尝试各种其他解决方案后,我将一个使用get_urls和一个直接定义到视图中的视图组合在一起,虽然它实际上只是将代码从多个django文件移动到管理界面中,但感觉更整洁 - 尽管它确实利用了admin包装器来阻止未经身份验证的用户,这是一种改进。
我将在这里留下一份工作代码的副本,供将来发现这一点的人使用,因为我看到很少有TreeEditor等人的例子。在较新版本的Django中使用。
class NodeAdmin(TreeEditor):
model = Node
# < ... > Other details removed for brevity
def get_urls(self):
urls = super(NodeAdmin, self).get_urls()
my_urls = [
url(r'^(?P<node_id>[0-9]+)/get_suggestions/$', self.admin_site.admin_view(self.get_suggestions)),
]
return my_urls + urls
def get_suggestions(self, request, node_id):
this_node = Node.objects.get(pk=node_id)
get_suggestions(this_node.pk)
messages.add_message(request, messages.SUCCESS, 'Requested suggestions for {0}'.format(this_node.term))
redirect_url = urlresolvers.reverse('admin:trinket_node_changelist')
return HttpResponseRedirect(redirect_url)
def _actions_column(self, obj):
actions = super(NodeAdmin, self)._actions_column(obj)
# Adds an 'get suggestions' action to the Node editor using a search icon
actions.insert(
0, u'<a title="{0}" href="{1}/get_suggestions"><img src="{2}admin/img/selector-search.gif" alt="{0}" /></a>'.format(
_('Get Suggestions'),
obj.pk,
settings.STATIC_URL,
)
)
# Adds an 'add child' action to the Node editor using a plus icon
actions.insert(
0, u'<a title="{0}" href="add/?{1}={2}"><img src="{3}admin/img/icon_addlink.gif" alt="{0}" /></a>'.format(
_('Add child'),
getattr(self.model._meta,'parent_attr', 'parent'),
obj.pk,
settings.STATIC_URL
)
)
return actions