1

I have a model called person like this

class person(models.Model):
    choice1 = ("a","DisplayNameA", "b", "DisplayNameB")
    choice1_field = models.CharField(max_length=1, choices=choice1)
    choice2 = ("c","DisplayNameC", "d", "DisplayNameD")
    choice2_field = models.CharField(max_length=1, choices=choice2)
    # and so on, there are many fields like these

After this, I am trying to generate a CSV file in my views

I can loop through all the fields I need and then access the values dynamically like this

getattr(person_object, field_name)

However this returns "a", "b" and so on.

I know I can access the display name using get_FOO_display(), where foo is the field's name. However, as the retrieval of the field is happening dynamically, is there a way to access the display name of a field dynamically? Without having to bind functions?

Swetank Poddar
  • 1,257
  • 9
  • 23

1 Answers1

6

You can pass get_fieldname_display to the getattr function:

getattr(person_object, 'get_{}_display'.format(field_name))()

or you can make use of the methodcaller of the operator package:

from operator import methodcaller

mygetter = methodcaller('get_{}_display'.format(field_name))

result = mygetter(person_object)
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • Python and its magic! That worked, thank you! So as per my understanding, the getattr function literally concats whatever I pass to the person_object "." followed by the field_name? Does it also mean that I can pass it arguments inside ```()```? – Swetank Poddar Apr 13 '20 at 17:07
  • 1
    @SwetankPoddar: you obtain a method yes, so the `getattr(person_object, 'get_fieldname_display')` will result in `person_object.get_fieldname_display`, we then call that function, so *yes* you can pass arguments inside the parenthesis at the end :) – Willem Van Onsem Apr 13 '20 at 17:09
  • Willem there you are again, helping me out. Thanks. – Milo Persic Aug 11 '22 at 21:28