== Admin change list view customization with ListColumn == Related ticket: #8054 Move method properties for admin list customization to ModelAdmin This ticket adds: * beautifully API to admin change list customization * ability to customize and localize 3rd-party application without fork it * ability to apply custom template filters on field value or model method returned value without any magic * ability to specify witch field will be used in order for column based on model method ==== ListColumn API ==== Arguments: * field_name - callable function or string with model field, Model method name or current ModelAdmin method name. Keyword arguments: * header - change list column header. If not provided standard algorithm to header column calculation will be used. * filter - template filters will be applied to value on output. It is string like this 'filter1|filter2:"arg"'. * load_filters - list of required template tags libraries. This libraries will be load before apply template filters to output value. Eg.: ['tagging_tags', 'tagging_autocomplete_tags']. Note: In admin area you can use "boolean_icon" template filter (it is provided by "admin_list" template library, this used to render admin change list). It is useful to display values of boolean fields or callables. It show green or red mark instead of True or False values. It is applied for boolean model fields (but not for callables) on render admin change list by default. * order_field - string with model field name witch will be used to provide order by this column. If it provided for callable functions, its will be called with this field value in first argument instead of current object instance (this feature exists at least at svn rev. 14188 but currently is not documented). * value_map - choices used to mapping display value. This can redefine choices from model field for shown in admin change list. If filter argument is provided, this is applied before template filters. ==== Example ==== Current way to admin change list view customization: {{{ class Account(models.Model): foo = model.BooleanField(...) bar = model.CharField(...) baz = model.CharField(...) bonk = model.CharField(...) ends = models.DateTimeField() def get_bar_column(self): return ... get_bar_column.allow_tags = True get_bar_column.short_description = 'Bar' def timeuntil_ends(): return ... class AccountAdmin(admin.ModelAdmin): list_display = ['foo', 'get_bar_column', 'baz', 'bonk', 'timeuntil_ends'] }}} Proposed way: {{{ class Account(models.Model): foo = model.BooleanField(...) bar = model.CharField(...) baz = model.CharField(...) bonk = model.CharField(...) ends = models.DateTimeField() def get_bar(self): return ... class AccountAdmin(admin.ModelAdmin): def formated_bonk(bonk): return ... list_display = [ admin.ListColumn('foo', header='Foo Description', filter='boolean_icon'), admin.ListColumn('get_bar', filter='safe', order_field='bar'), 'baz', 'bonk', admin.ListColumn('ends', filter='timeuntil', header="Ending in"), admin.ListColumn('formated_bonk', order_field="bonk") ] }}}