Admin tabs

Admin Tabs in change form

A templatetag to create a tabbed layout in a change_form. It looks in ModelAdmin for method get_tabs.

that means you can just set tabs in you ModelAdmin.

Tabs is a tuple of tuples. An example of a hypothetical Company model whose Inlines are Contacts and Banks:

tabs = (
  (_('Company'), {'items': [_('general_info')]}),
  (_('Contacts'), {'items': [Contact, ], 'active': True}),
  (_('Addresses'), {'items': [AddressInline, Banks], 'active': True}),
  (_('Banks'), {'items': [BankInline], 'active': True}),
)
../_images/admin_tabs.png

Resulting in 4 tabs with labels as shown in the figure. Each element of tabs is a tuple composed of:

  • a label

  • a list of elements (possibly empty). Each element can be eather a

    • string

      that will be interpreted as the name of a fieldset declared in fieldsets

    • (django) Inline

      whose inline must be declared in the standard way. (In this case a models can also be used)

    • AjaxInline

      whose inline must be declared as defined ref:here <ajax-inline>

    • empty list

      the first one that is left as an empty list will be filled with all fieldsets as in:

      (_('Author'), {}),
      

This grants the ability to place all peaces in any fancy way

get_tabs

The signature if function get_tabs() is as follows:

def get_tabs(self, request, obj):
   return self.tabs

Nota

to use get_tabs returning different tabs depending on obj requires you also create inlines with the same logic.

That means you have at least django 1.5 when kw obj was added to get_inline_instances!!

Note that if your get_tabs changes the number of Inlines used you need to prepare a similar get_inline_instances that must on turn call super as in:

def get_tabs(self, request, obj=None):
    if obj and obj.id:
        tabs = self.tabs
    else:
        tabs = (
            ('Contratto' , {}),
            )
    return tabs

def get_inline_instances(self, request, obj=None):

    if obj and obj.id:
        self.inlines = self.inlines
    else:
        self.inlines = []
    return super(self.__class__, self).get_inline_instances(request, obj)