Opened 9 months ago

Closed 9 months ago

#35177 closed Bug (invalid)

Admin.display decorator functions do not output correct-format for 'modern' Python string-formatting

Reported by: Stephen Skett Owned by: nobody
Component: contrib.admin Version: 4.2
Severity: Normal Keywords: admin, display, string, format,
Cc: Stephen Skett Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Stephen Skett)

I am trying to write an admin display function (using the admin.display decorator) to output the values of a float-field to 3 decimal places.

Seemed like this should be pretty simple, and indeed it is, IF you use 'old-style' Python format-strings, e.g.

class ModelFoo_Admin(admin.ModelAdmin):
    @admin.display
    def get_value_to_3dp(self, obj):
        return "%.3f" % obj.bar

However, if you use either of the more 'modern'-style Python string-formatting methods (i.e. str.format or formatted string-literals), the specified string is not displayed using the specified formatting, i.e. this:

class ModelFoo_Admin(admin.ModelAdmin):
    @admin.display
    def get_value_to_3dp(self, obj):
        return "{0:3f}".format(obj.bar)

or this:

class ModelFoo_Admin(admin.ModelAdmin):
    @admin.display
    def get_value_to_3dp(self, obj):
        return f'{obj.bar:3f}'

display the output string to the default number of decimal-places (in my case, 6), with trailing zeroes, rather than to 3 decimal places as expected.

I don't understand why there would be any difference between these approaches, so I am assuming this is a bug rather than the intended behaviour.

Change History (2)

comment:1 by Stephen Skett, 9 months ago

Description: modified (diff)

comment:2 by Baptiste Mispelon, 9 months ago

Resolution: invalid
Status: newclosed

Hi,

The equivalent of "%.3f" % obj.bar is "{0:.3f}".format(obj.bar) (note the added .).

What you're doing with "{0:3f}".format(obj.bar) is making sure the final string is at least 3 characters long, using the default 6 decimal places (try replacing the 3 by a 10 for example, you'll see extra spaces at the beginning of the string).

So Django is not doing anything weird here.

Note: See TracTickets for help on using tickets.
Back to Top