用于FeinCMS操作列的{Django自定义管理操作

时间:2015-09-28 11:40:44

标签: python django django-mptt feincms

我正在使用FeinCMS TreeEditor接口为Django-Mptt树结构创建一个管理面板。此接口为每个节点提供一个“操作列”,用于快速添加或移动节点,而无需使用典型的Django管理操作选择框。

Example inteface from Django/TreeEditor/MPTT app

我想要做的是向此集合添加一个自定义管理操作,该操作将节点的pk传递给芹菜任务,然后该任务将添加一组节点作为子节点。现有的函数只是指向该任务的URL的href链接(添加/删除/移动),所以到目前为止我只是模仿了这个。

我的解决方案目前涉及:

  1. 将操作定义为模型上的函数
  2. 创建一个使用此功能的视图并重定向回更改列表
  3. 将此视图添加到管理网址
  4. 将TreeEditor操作列超级化为ModelAdmin类
  5. 向调用此网址的集合添加操作
  6. 当然必须有比这更好的方法吗?它有效,但感觉非常复杂和不干,我相信它会以奇怪的方式打破。

    不幸的是,我只用了一两个月就开始使用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
    

    请注意,如果您尝试执行此代码,我可能已经破坏了重命名并删除了无关紧要的内容,我认为它应该充分说明我在这里尝试做的事情。

1 个答案:

答案 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
相关问题