我之前已经让一个 django 应用程序在不修改实际管理代码的情况下精确地做到这一点。而是通过使用查询集过滤器扩展的几个方法创建 admin.ModelAdmin 的子类。这将仅显示用户拥有的记录(在这种情况下,业务是 AUTH_PROFILE_MODEL)。网上有很多关于如何实现这一点的博客。
您可以使用此技术过滤列表、表单选择框、表单字段验证保存等。
到目前为止,它从 NFA 到 1.0 到 1.1 都幸存下来,但这种方法容易受到 api 变化的影响。
在实践中,我发现为应用程序中的新模型生成新的行级别访问级别管理表单要快得多,因为我已经添加了它们。您只需使用用户 fk 创建一个新模型,子类化 AdminFilterByBusiness 或只是
admin.site.register(NewModel,AdminFilterByBusiness)
如果它不需要任何定制。它有效并且非常干燥。
但是,您确实冒着无法利用其他已发布的 django 应用程序的风险。因此,请为您正在构建的项目仔细考虑这种技术。
下面的示例过滤器管理类受http://code.djangoproject.co/wiki/NewformsHOWTO的启发
#AdminFilterByBusiness {{{2
class AdminFilterByBusiness(admin.ModelAdmin):
"""
Used By News Items to show only objects a business user is related to
"""
def has_change_permission(self,request,obj=None):
self.request = request
if request.user.is_superuser:
return True
if obj == None:
return super(AdminFilterByBusiness,self).has_change_permission(request,obj)
if obj.business.user == request.user:
return True
return False
def has_delete_permission(self,request,obj=None):
self.request = request
if request.user.is_superuser:
return True
if obj == None:
return super(AdminFilterByBusiness,self).has_delete_permission(request,obj)
if obj.business.user == request.user:
return True
return False
def has_add_permission(self, request):
self.request = request
return super(AdminFilterByBusiness,self).has_add_permission(request)
def queryset(self, request):
# get the default queryset, pre-filter
qs = super(AdminFilterByBusiness, self).queryset(request)
#
if not (request.user.is_superuser):
# filter only shows blogs mapped to currently logged-in user
try:
qs = qs.filter(business=request.user.business_set.all()[0])
except:
raise ValueError('Operator has not been created. Please Contact Admins')
return qs
def formfield_for_dbfield(self, db_field, **kwargs):
""" Fix drop down lists to populate as per user request """
#regular return for superuser
if self.request.user.is_superuser:
return super(AdminFilterByBusiness, self).formfield_for_dbfield(
db_field, **kwargs)
if db_field.name == "business":
return forms.ModelChoiceField(
queryset = self.request.user.business_set.all()
)
#default
return super(AdminFilterByBusiness, self).formfield_for_dbfield(db_field, **kwargs)