BLOG
Enjoy when you can, and endure when you must.
NOV 13, 2013/Django
在ModelAdmin中添加自定义View

为拓展ModelAdmin的功能,我们时常需要通过自定义View来进行拓展,通过利用ModelAdmin.get_urls(self)可以很方便的做到这一点。

ModelAdmin中的get_urls方法返回该ModelAdmin中特定的URLs,其采用的方式和URLConf一样。由此,我们只需加入自己的View函数并通过get_urls方法加入URL链接即可达到目的。以下是我自己网站的一个示例:

class PhotoAdmin(admin.ModelAdmin):

    ......
    
    def get_urls(self):
        from django.conf.urls import patterns, url
        info = self.model._meta.app_label, self.model._meta.module_name
        return patterns('',
                        url(r'^(\d+)/top/$',
                            self.admin_site.admin_view(self.set_top),
                            name='%s_%s_top' % info),
                            
                        ......
                     
                        ) + super(PhotoAdmin, self).get_urls()
    ......

    def set_top(self, request, object_id, from_url=''):
        photo = get_object_or_404(self.queryset(request), pk=object_id)
        photo.on_top = True
        photo.save()
        return HttpResponseRedirect(from_url or reverse('admin:dshare_photo_changelist'))

该代码截取自dshare/admin.py,这里我需要增加一个View来手动选取置顶图片。因此,我在PhotoAdmin中增加了一个set_top方法,把指定图片的on_top属性置为1,最后将操作者重定向到图片管理列表页。

然后,我们重写get_urls方法,加入我自己的URL并将原有的admin URLs重新添加在后面。这通常是必须的做法,Django官方文档有专门提到:

Notice that the custom patterns are included before the regular admin URLs: the admin URL patterns are very permissive and will match nearly anything, so you’ll usually want to prepend your custom URLs to the built-in ones.

另外值得注意的是,自定义的View本身不会进行权限验证并可能受缓存的影响。不过Django本身提供了一个包装函数以避免这些问题,即我在urlpatterns里面所使用的的AdminSite.admin_view()。

更多可以参考Django官方文档。

COMMENTS
LEAVE COMMNT