覆盖特定模型的Django管理员URL?

Chr*_*att 7 django url django-urls django-admin

首先是一点背景:

我有一个Event有各种各样event_type的模型.我想打破其中一个事件类型,'电影',进入它自己的管理员.我有基本的功能:一个代理模型继承自Event命名Film,该代理模型的自定义管理器,它只将其过滤为"电影"事件类型,它是自己的ModelAdmin.

问题是相反的.我现在需要从主Event管理员中过滤掉电影.我不想改变Event模型或其默认管理器,因为影响太大了.因此,我尝试创建另一个代理模型,EventAdminProxy其唯一目的是在管理员中提供过滤的事件列表.然后,我Event使用现有的ModelAdmin 注册此模型,而不是.

这显然有效,但它有改变管理员URL的不幸副作用.而不是更改列表位于"/ admin/event/event /",它现在位于"/ admin/event/eventadminproxy /".

我要做的是保持这个设置,但也保留旧的URL.我试过重载ModelAdmin的get_urls方法,但从我所知道的,你无法控制那里的完整URL,只有"/ app_label/model_class /"之后的内容.

我想在主urls.py中覆盖它,但无法找出可接受的视图.实际视图仅在实例化的ModelAdmin对象上可用,而不是类本身.

有关如何覆盖管理员中使用的URL的任何想法?

Jj.*_*Jj. 8

查看Django源,管理URL在两个位置,ModelAdmin实例和实例中构建AdminSite.

要更改的部分是在AdminSite实例(django.contrib.admin.sites.AdminSite)中构建的,您可以将其子类化并覆盖该get_urls方法.如果你看一下方法的后半部分,你会看到:

    # Add in each model's views.
    for model, model_admin in self._registry.iteritems():
        urlpatterns += patterns('',
            url(r'^%s/%s/' % (model._meta.app_label, model._meta.module_name),
                include(model_admin.urls))
        )
Run Code Online (Sandbox Code Playgroud)

它正在添加模型的._meta.module_name,它只是模型的名称lowercased(django.db.models.options.Options.contribute_to_class).

一个简单的方法是覆盖Site的get_urls方法并为Proxy模型添加一个dict或特殊情况,这样它就会使用不同的url而不是model._meta.module_name一些东西:

class MyAdminSite(AdminSite):

module_name_dict = {
    EventAdminProxy: 'myfunkymodulename'
}

def get_urls(self):
    base_patterns = super(MyAdminSite, self).get_urls()
    my_patterns = patterns('',)

    for model, model_admin in self._registry.iteritems():
        if model in self.module_name_dict:
            module_name = self.module_name_dict[model]
            my_patterns += patterns('',
                url(r'^%s/%s/' % (model._meta.app_label, module_name),
                    include(model_admin.urls))
            )

    return my_patterns + base_patterns
Run Code Online (Sandbox Code Playgroud)


ari*_*rie 6

你可以重写查询集法你的EventModelAdmin和过滤的queryset,使电影,事件被排除在外.

与此类似的东西:

class EventAdmin(admin.ModelAdmin):

    def queryset(self, request):
        qs = super(EventAdmin, self).queryset(request)
        return qs.exclude(event_type='film')
Run Code Online (Sandbox Code Playgroud)