Hide Inline form in Django
My Django ModelAdmin shows different forms in dependency on user permissions. I've solved it with ModelForm's (get_form, get_fieldsets), but what to do with inlines?
class NewsAdmin(admin.ModelAdmin):
form = NewsAdminForm
writing_form = 开发者_如何学JAVANewsWritingForm
inlines = (LinkInline, FileInline)
ModelAdmin initializes them in ModelAdmin.__init__()
before getting request object. The only way seems to use CSS to hide them.
You can use ModelAdmin get_inline_instances function. Following code removes inlines from add_view:
from django.contrib import admin
from models import FooModel
class FooInline(admin.StackedInline):
model = FooModel
class MyModelAdmin(admin.ModelAdmin):
inlines = [FooInline]
def get_inline_instances(self, request, obj=None):
return obj and super(MyModelAdmin, self).get_inline_instances(request, obj) or []
ModelAdmin.__init__()
takes the classes in ModelAdmin.inlines
, instantiates them, and stores the results in ModelAdmin.inline_instances
. You can set ModelAdmin.inline_instances
to an empty list after __init__
to remove the inlines.
See line 243 of django/contrib/admin/options.py
I solved this by putting the logic to set self.inline_instances = []
in the get_readonly_fields(self, request, obj=None)
method.
For example, if you wanted to show the inlines to superusers but not to anyone else:
def get_readonly_fields(self, request, obj=None):
if request.user.is_superuser:
return ()
else:
self.inline_instances = []
return ()
I used bskinner's trick to hide inlines when adding a new object, with two adjustments: First, I had to overwrite "inlines", not "inline_instances", and second, make sure you always return self.readonly_fields, to make sure you are preserving those when they are set.
def get_readonly_fields(self, request, obj=None):
if obj:
# edit mode... add fields here to make them read-only when editing
return self.readonly_fields
else:
self.inlines = []
return self.readonly_fields
精彩评论