3

Quick question regarding some syntax when creating django models. If you take a look at the example models.py file below, you'll see that each of the four fields contain a repeat of the field name as a string in parentheses preceded my an underscore. I assume this is some kind of visual representation for when this is encountered in a form, but that seems to happen automatically in admin with out the _('field name').

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    date_joined = models.DateTimeField(_('date joined'), auto_now_add=True)
Andy
  • 708
  • 1
  • 11
  • 32
  • Is this code someone else wrote and you are now maintaining? – Red Cricket Nov 25 '18 at 00:28
  • No, it's from a tutorial I stumbled upon pertaining to extending the django user model. – Andy Nov 25 '18 at 00:29
  • 1
    The `_(string)` is not related to Django. I personally find using goofy stuff like that very un-useful in code. I asked about that sort of thing once here: https://stackoverflow.com/questions/52898415/what-does-foo-mean-in-python and got an ear full. – Red Cricket Nov 25 '18 at 00:32
  • Thank you. I will read into those answers. – Andy Nov 25 '18 at 00:35
  • In my question the answer turned out to be that at the top of the python file there was this `from django.utils.translation import pgettext_lazy, ugettext_lazy as _`. Maybe I was even following the same tutorial you are look at :-))) – Red Cricket Nov 25 '18 at 00:38
  • Yup, here is what I am seeing above in the imports: "from django.utils.translation import ugettext_lazy as _" – Andy Nov 25 '18 at 00:41
  • Glad I wasn't the only one confused by that `_` nonsense. – Red Cricket Nov 25 '18 at 00:44

1 Answers1

2

All of the built-in field types inherit from the Field class. If you look at the __init__() call for that class, you'll see that the first parameter in the function is the verbose_name parameter. So that tells us what these strings map to.

The _('some text') construct is a fairly prevalent syntax for doing internationalization (also known as i18n). I've seen this syntax in other languages like PHP. This allows the verbose name to be rendered in various languages when the code is translated. As you note in the comments above, the function ugettext_lazy is imported as the alias _. This allows programmers (all of whom are lazy), to type _('some text') instead of ugettext_lazy('some text') in every location where text needs to be translated. Since there could be hundreds (or thousands) of hard coded strings in an application, it saves the programmer lots of time in the long run.

It's an ugly hack, but it gets the job done. I dislike it particularly in Python since it overrides the sometimes useful _ name, which often gets used as a placeholder variable name when you want to throw a value away.

Jonah Bishop
  • 12,279
  • 6
  • 49
  • 74