So it seems that there’s technically no difference as of Django 1.5. Template engine internally marks a variable for translation (by setting its translate attribute) in two cases:
- when you do
{% trans VAR %}(seeTranslateNode), or - if the name of a variable starts with
_(and ends with)(seeVariable.__init__).
Later, when the variable is being resolved, Django wraps it with ugettext or pgettext if it sees the translate attribute.
However, as can be seen from source code, there are some flexibility considerations in favor of {% trans %} tag:
- you can do
{% trans "String" noop %}, which will put the string for translation into .po files, but won’t actually translate the output when rendering (no internaltranslateattribute on variable, nougettextcall); - you can specify message context*, like
{% trans "May" context "verb" %}; - you can put translated message into a variable for later use*, like
{% trans "String" as.
translated_string %}
* As of Django 1.4.
Please feel free to correct me or post a better answer in case I’m missing anything.