动态模型管理员与管理员注册模型的方式不能很好地协同工作。
我建议在 CategoryAdmin 中创建子视图。
from django.conf.urls import patterns, url
from django.contrib import admin
from django.contrib.admin.options import csrf_protect_m
from django.contrib.admin.util import unquote
from django.core.urlresolvers import reverse
from demo_project.demo.models import Category, Tag
class TagAdmin(admin.ModelAdmin):
# as long as the CategoryTagAdmin class has no custom change_list template
# there needs to be a default admin for Tags
pass
admin.site.register(Tag, TagAdmin)
class CategoryTagAdmin(admin.ModelAdmin):
""" A ModelAdmin invoked by a CategoryAdmin"""
read_only_fields = ('category',)
def __init__(self, model, admin_site, category_admin, category_id):
self.model = model
self.admin_site = admin_site
self.category_admin = category_admin
self.category_id = category_id
super(CategoryTagAdmin, self).__init__(model, admin_site)
def queryset(self, request):
return super(CategoryTagAdmin, self).queryset(request).filter(category=self.category_id)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('name', 'tag_changelist_link')
def tag_changelist_link(self, obj):
info = self.model._meta.app_label, self.model._meta.module_name
return '<a href="%s" >Tags</a>' % reverse('admin:%s_%s_taglist' % info, args=(obj.id,))
tag_changelist_link.allow_tags = True
tag_changelist_link.short_description = 'Tags'
@csrf_protect_m
def tag_changelist(self, request, *args, **kwargs):
obj_id = unquote(args[0])
info = self.model._meta.app_label, self.model._meta.module_name
category = self.get_object(request, obj_id)
tag_admin = CategoryTagAdmin(Tag, self.admin_site, self, category_id=obj_id )
extra_context = {
'parent': {
'has_change_permission': self.has_change_permission(request, obj_id),
'opts': self.model._meta,
'object': category,
},
}
return tag_admin.changelist_view(request, extra_context)
def get_urls(self):
info = self.model._meta.app_label, self.model._meta.module_name
urls= patterns('',
url(r'^(.+)/tags/$', self.admin_site.admin_view(self.tag_changelist), name='%s_%s_taglist' % info )
)
return urls + super(CategoryAdmin, self).get_urls()
admin.site.register(Category, CategoryAdmin)
类别更改列表中的项目有一个额外的列,其中包含一个由tag_changelist_link 指向CategoryAdmin.tag_changelist 的链接。此方法创建一个具有一些附加功能的 CategoryTagAdmin 实例并返回其 changelist_view。
这样您就可以在每个类别上都有一个过滤的标签更改列表。要修复 tag_changelist 视图的面包屑,您需要将 CategoryTagAdmin.change_list_template 设置为 {% extends 'admin/change_list.html' %} 并覆盖 {% block breadcrumbs %} 的自己的模板。这就是您需要来自 extra_context 的 parent 变量来创建正确 URL 的地方。
如果您计划实现 tag_changeview 和 tag_addview 方法,您需要确保在各种管理模板中呈现的链接指向正确的 url(例如,使用 form_url 作为参数调用 change_view)。
CategoryTagAdmin 上的 save_model 方法可以在添加新标签时设置默认类别。
def save_model(self, request, obj, form, change):
obj.category_id = self.category_id
super(CategoryTagAdmin, self).__init__(request, obj, form, change)
如果你仍然想坚持 apache 重启方法......是的,你可以重启 Django。这取决于您如何部署实例。
在 apache 上,您可以触摸将重新加载实例 os.utime(path/to/wsgi.py 的 wsgi 文件。
使用 uwsgi 时可以使用uwsgi.reload()。
您可以查看Rosetta 的源代码,他们在保存翻译后如何重启实例(views.py)。