如何覆盖Django admin`change_list.html`以便随时提供格式

时间:2018-03-12 07:28:51

标签: django django-templates

在Django admin中,如果我想显示Iron列表及其各自的格式化权重,我必须这样做。

class IronAdmin(admin.ModelAdmin):
    model = Iron
    fields = ('weight_formatted',)

def weight_formatted(self, object):
    return '{0:.2f} Kg'.format(object.weight)
weight_formatted.short_description = 'Weight'

I.e: 500.00 Kg

然而,问题是我必须为每个要格式化的字段编写一个方法,当我有10个或更多要格式化的对象时,它会变得多余。

是否有一种方法可以覆盖以“捕获”这些值并在它们呈现到html之前指定格式?即而不是必须为每个Admin类编写一个方法,我可以编写以下内容并将其格式化。

class IronAdmin(admin.ModelAdmin):
    model = Iron
    fields = ('weight__kg',)

def overriden_method(field):
    if field.name.contains('__kg'):
        field.value = '{0:.2f} Kg'.format(field.value)

I.e: 500.00 Kg

1 个答案:

答案 0 :(得分:0)

经过几个小时的搜索,我终于想通了!我意识到这不是最有效的代码,在大多数用例中它可能比它的价值更麻烦但对我来说已经足够了。如果其他人需要快速而肮脏的方式来做到这一点:

为了使其自动化,我必须使用以下内容覆盖django.contrib.admin.templatetags.admin_list.result_list

def result_list_larz(cl):
    """
    Displays the headers and data list together
    """
    resultz = list(results(cl))  # Where we override

    """ Overriding starts here """
    """ Have to scrub the __kg's as result_header(cl) will error out """
    for k in cl.list_display:
        cl.list_display[cl.list_display.index(k)] = k.replace('__kg','').replace('__c','')
    headers = list(result_headers(cl))

    num_sorted_fields = 0
    for h in headers:
        if h['sortable'] and h['sorted']:
            num_sorted_fields += 1
    return {'cl': cl,
            'result_hidden_fields': list(result_hidden_fields(cl)),
            'result_headers': headers,
            'num_sorted_fields': num_sorted_fields,
            'results': resultz}

然后覆盖results(cl)items_for_result()的调用,然后我们覆盖对lookup_field()的调用,如下所示:

def lookup_field(name, obj, model_admin=None):
opts = obj._meta
try:
    f = _get_non_gfk_field(opts, name)
except (FieldDoesNotExist, FieldIsAForeignKeyColumnName):
    # For non-field values, the value is either a method, property or
    # returned via a callable.
    if callable(name):
        attr = name
        value = attr(obj)
    elif (model_admin is not None and
            hasattr(model_admin, name) and
            not name == '__str__' and
            not name == '__unicode__'):
        attr = getattr(model_admin, name)
        value = attr(obj)

    """ Formatting code here """
    elif '__kg' in name or '__c' in name:  # THE INSERT FOR FORMATTING!

        actual_name = name.replace('__kg','').replace('__c', '')
        value = getattr(obj, actual_name)
        value = '{0:,.2f}'.format(value)

        prefix = ''
        postfix = ''
        if '__kg' in name:
            postfix = ' Kg'
        elif '__c' in name:
            prefix = 'P'

        value = '{}{}{}'.format(prefix, value, postfix)
        attr = value
    else:
        attr = getattr(obj, name)
        if callable(attr):
            value = attr()
        else:
            value = attr
    f = None
    """ Overriding code END """

else:
    attr = None
    value = getattr(obj, name)
return f, attr, value