Making inlines conditional in the Django admin
As of Django 2.2.2 (current latest version as of this writing), I would use the solution provided earlier by @aggieNick02, which is to override get_inline_instances
shown below.
class ThingAdmin(models.ModelAdmin):
inlines = [MyInline,]
def get_inline_instances(self, request, obj=None):
if not obj or obj.date >= today: return []
return super(ThingAdmin, self).get_inline_instances(request, obj)
I'm posting this new answer because as of April 17th, 2019 in this commit, it looks like the future recommended way to do this would be to instead override the get_inlines
method. So in later versions, the solution to this could look like the code below, which allows you to specify different sets of inlines and use them based on a condition.
class ThingAdmin(admin.ModelAdmin):
model = Thing
inlines = [inline]
other_set_of_inlines = [other_inline]
def get_inlines(self, request, obj):
if obj.date > datetime.date(2012, 1, 1):
return self.inlines
else:
return self.other_set_of_inlines
Thanks to the comments for a change in 1.4. My implementation here wasn't thread safe either, so it really should have been deleted.
Since get_formsets
is passed the object and calls get_inline_instances
, we can modify both functions to act on the object.
This should work:
class ThingAdmin(admin.ModelAdmin):
model = Thing
inlines = [inline]
other_set_of_inlines = [other_inline]
def get_inline_instances(self, request, obj=None):
# ^^^ this is new
inline_instances = []
if obj.date > datetime.date(2012, 1, 1):
inlines = self.inlines
else:
inlines = self.other_set_of_inlines
for inline_class in inlines:
inline = inline_class(self.model, self.admin_site)
if request:
if not (inline.has_add_permission(request) or
inline.has_change_permission(request) or
inline.has_delete_permission(request)):
continue
if not inline.has_add_permission(request):
inline.max_num = 0
inline_instances.append(inline)
return inline_instances
def get_formsets(self, request, obj=None):
for inline in self.get_inline_instances(request, obj):
# ^^^^^ this is new
yield inline.get_formset(request, obj)