Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8988893
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T22:07:20+00:00 2026-06-15T22:07:20+00:00

Why does get_FOO_display() return integer value when logging info (django)? I have a model

  • 0

Why does get_FOO_display() return integer value when logging info (django)?

I have a model field that is using a choice to restrict its value. This works fine
and I have it working everywhere within the app, except when logging information,
when the get_FOO_display() method returns the underlying integer value instead
of the human-readable version.

This is the model definition (abridged):

THING_ROLE_MONSTER = 0
THING_ROLE_MUMMY = 1

ROLE_CHOICES = (
    (THING_ROLE_MONSTER, u'Monster'),
    (THING_ROLE_MUMMY, u'Mummy'),
)

# definition of property within model
class Thing(models.Model):
    ...
    role = models.IntegerField(
        'Role',
        default=0,
        choices=ROLE_CHOICES
    )

If I run this within the (django) interactive shell it behaves exactly as you would expect:

>>> from frankenstein.core.models import Thing
>>> thing = Thing()
>>> thing.role = 0
>>> thing.get_role_display()
u'Monster'

However, when I use exactly the same construct within a string formatting / logging
scenario I get the problem:

logger.info('New thing: <b>%s</b>', thing.get_role_display())

returns:

New thing: <b>0</b> 

Help!

[UPDATE 1]

When I run the logging within the interactive shell I get the correct output:

>>> from frankenstein.core.models import Thing
>>> import logging
>>> thing = Thing()
>>> thing.role = 0
>>> logging.info('hello %s', b.get_role_display())
INFO hello Monster

[UPDATE 2] Django internals

Following up on the answer from @joao-oliveira below, I have dug into the internals and uncovered the following.

The underlying _get_FIELD_display method in django.db.models looks like this:

def _get_FIELD_display(self, field):
    value = getattr(self, field.attname)
    return force_unicode(dict(field.flatchoices).get(value, value), strings_only=True)

If I put a breakpoint into the code, and then run ipdb I can see that I have the issue:

ipdb> thing.get_role_display()
u'1'
ipdb> thing._get_FIELD_display(thing._meta.get_field('role'))
u'1'

So, the fix hasn’t changed anything. If I then try running through the _get_FIELD_display method code by hand, I get this:

ipdb> fld = thing._meta.get_field('role')
ipdb> fld.flatchoices
[(0, 'Monster'), (1, 'Mummy')]
ipdb> getattr(thing, fld.attname)
u'1'
ipdb> value = getattr(thing, fld.attname)
ipdb> dict(fld.flatchoices).get(value, value)
u'1'

Which is equivalent to saying:

ipdb> {0: 'Monster', 1: 'Mummy'}.get(u'1', u'1')
u'1'

So. The problem we have is that the method is using the string value u'1' to look up the corresponding description in the choices dictionary, but the dictionary keys are integers, and not strings. Hence we never get a match, but instead the default value, which is set to the existing value (the string).

If I manually force the cast to int, the code works as expected:

ipdb> dict(fld.flatchoices).get(int(value), value)
'Mummy'
ipdb> print 'w00t'

This is all great, but doesn’t answer my original question as to why the get_foo_display method does return the right value most of the time. At some point the string (u’1′) must be cast to the correct data type (1).

[UPDATE 3] The answer

Whilst an honourable mention must go to Joao for his insight, the bounty is going to Josh for pointing out the blunt fact that I am passing in the wrong value to begin with. I put this down to being an emigre from ‘strongly-typed-world’, where these things can’t happen!

The code that I didn’t include here is that the object is initialised from a django form, using the cleaned_data from a ChoiceField. The problem with this is that the output from a ChoiceField is a string, not an integer. The bit I missed is that in a loosely-typed language it is possible to set an integer property with a string, and for nothing bad to happen.

Having now looked into this, I see that I should have used the TypedChoiceField, to ensure that the output from cleaned_data is always an integer.

Thank you all.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T22:07:21+00:00Added an answer on June 15, 2026 at 10:07 pm

    I’m really sorry if this sounds condescending, but are you 100% sure that you’re setting the value to the integer 1 and not the string ‘1’?

    I’ve gone diving through the internals and running some tests and the only way that the issue you’re experiencing makes sense is if you’re setting the value to a string. See my simple test here:

    >>> from flogger.models import TestUser
    >>> t = TestUser()
    >>> t.status = 1
    >>> t.get_status_display()
    u'Admin'
    >>> t.status = '1'
    >>> t.get_status_display()
    u'1'
    

    Examine your view code, or whatever code is actually setting the value, and examine the output of the field directly.

    As you pasted from the internal model code:

    def _get_FIELD_display(self, field):
        value = getattr(self, field.attname)
        return force_unicode(dict(field.flatchoices).get(value, value), strings_only=True)
    

    It simply gets the current value of the field, and indexes into the dictionary, and returns the value of the attribute if a lookup isn’t found.

    I’m guessing there were no errors previously, because the value is coerced into an integer before being inserted into the database.

    Edit:

    Regarding your update mentioning the type system of python. Firstly, you should be using TypedChoiceField to ensure the form verifies the type that you expect. Secondly, python is a strongly typed language, but the IntegerField does its own coercing with int() when preparing for the database.

    Variables are not typed, but the values within them are. I was actually surprised that the IntegerField was coercing the string to an int also. Good lessen to learn here – check the basics first!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

If I have a proc that needs to return an array to its caller,
I have a form and a div within that form that I am using
I'm using NetBeans as my IDE. Whenever I have some code that uses another
Does file_get_contents maintain line breaks? I thought it did but I have tried this:
I have a ListView item in my application. The scroll position does not get
I know that this question might have been asked like 100 times, but, believe
I'm fairly sure that I am not insane, but I do have memories of
Here's the scenario: We have a creative team that operates in Flash CS5.5 and
My model has a boolean that has to be nullable public bool? Foo {
In this hypothetical example, imagine I have an object FooSet that has five properties

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.