除了通常的管理员,我想为非员工用户创建一个有限的管理员。这个管理员网站将有不同的已注册的ModelAdmin
。
我在我的项目目录中创建了一个名为/useradmin/的文件夹,并类似于contrib/admin/_init_.py添加了一个autodiscover()函数,它将注册在useradmin.py模块中定义的模型,而不是在admin.py中定义的模型:
# useradmin/__init__.py
def autodiscover():
# Same as admin.autodiscover() but registers useradmin.py modules
...
for app in settings.INSTALLED_APPS:
mod = import_module(app)
try:
before_import_registry = copy.copy(site._registry)
import_module('%s.useradmin' % app)
except:
site._registry = before_import_registry
if module_has_submodule(mod, 'useradmin'):
raise
我还创建了useradmin/sites.py文件,覆盖了类似contrib/admin/sites的AdminSite。
# useradmin/sites.py
class UserAdminSite(AdminSite):
def has_permission(self, request):
# Don't care if the user is staff
return request.user.is_active
def login(self, request):
# Do the login stuff but don't care if the user is staff
if request.user.is_authenticated():
...
else:
...
site = UserAdminSite(name='useradmin')
在项目的URL中:
# urls.py
from django.contrib import admin
import useradmin
admin.autodiscover()
useradmin.autodiscover()
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
(r'^useradmin/', include(useradmin.site.urls)),
)
我尝试在app目录下的admin.py和useradmin.py模块中注册不同的模型:
# products/useradmin.py
import useradmin
class ProductAdmin(useradmin.ModelAdmin):
pass
useradmin.site.register(Product, ProductAdmin)
但是当我在useradmin.py中像这样注册模型useradmin.site.register(Product, ProductAdmin)
时,我会得到一个'module' object has no attribute 'ModelAdmin'
的异常。虽然当我通过shell尝试时;
import useradmin
from useradmin import ModelAdmin
没有引发任何异常。
有什么想法可能出了问题吗?
编辑:
我尝试按照 @Luke 的方式排列代码,尽可能地简化如下: (文件路径相对于项目根目录)
# admin.py
from django.contrib.admin import autodiscover
from django.contrib.admin.sites import AdminSite
user_site = AdminSite(name='useradmin')
# urls.py (does not even have url patterns; just calls autodiscover())
import admin
admin.autodiscover()
# products/admin.py
import admin
from products.models import Product
admin.user_site.register(Product)
作为结果,当在
products/admin.py
中调用admin.user_site.register(Product)
时,我会得到一个AttributeError: 'module' object has no attribute 'user_site'
错误。
有什么想法吗?
解决方案:
我不知道是否有更好的方法,但是将项目根目录中的admin.py
重命名为useradmin.py
并相应地更新导入可以解决最后一种情况,即命名和导入冲突。
contrib.admin
中导入的,位于useradmin/init.py中。useradmin/init.py和contrib.admin.init.py中的导入语句是相同的。因此,我可以像这样导入ModelAdmin:from useradmin import ModelAdmin
。我想要一些超出文档所述方式的自定义。例如,用户在具有FK字段添加权限的情况下不应在管理员主页面中看到某些查找模型。因此,我需要实现自己的autodiscover()来仅向用户的管理站点注册某些模型。 - onurmatikAdminSite
实例中(autodiscover
为你做的唯一一件事情就是查找admin.py
文件),而无需进行所有这些重复操作 - 你甚至可以编写自己的AdminSite
类,继承自Django的类,以便按照你的意愿进行设置。 - girasquiduser_admin = AdminSite(name='user_admin')
,并使用原始的admin.site.register(ModelA)
注册一些模型,以及使用admin.user_site(ModelB)
注册其他模型。这是有意义的。但是我仍然无法在实践中解决循环导入问题。如果/当我成功时,我会发布代码片段。谢谢。 - onurmatikadmin.py
更改为useradmin.py
并相应地更新了导入。现在它按预期工作。谢谢。 - onurmatik