oTree Forum >

Format numbers without Django

#1 by kikenc49

Hi all, after the update of oTree the number displayed on the project I work are now unformatted, i.e. 1000000 instead of 1.000.000 for example. This was previously handle by `intcomma` inside the Django template `django.contrib.humanize`. Any ideas how to make this happen now outside Django framework?
Thanks in advance.

#2 by BonnEconLab

One (and fail-safe) way is to move the formatting to Python, that is, to the __init__.py file. In other words, you convert the number to a (formatted) string and then display that string in your HTML template.

See my suggestions in https://www.otreehub.com/forum/662/.

Alternatively, you could use JavaScript to search for numbers in your HTML page and replace them by a formatted version, but that seems much more complicated (and error-prone) to me.

#3 by kikenc49 (edited )

Thanks for the tip BonnEconLab. I implemented this and it works although I am having issues to access to specific variables for each player on the templates (the ones defined under the class Player). 
I defined two extra methods to format the numbers in Python (format_number and format_money) following your suggestion and call the variables I want to format as their returns.
These variables are stored in a dict as the return of another method (generate_vars_for_templates) which is called on the vars_for_templates on each class for the page I want to access those variables:

class Template(Page):
    ...
    def vars_for_template(player):
            players = player.subsession.get_players()
            return player.group.generate_vars_for_templates(players)

Here is the other method:

class Group:
    ....
    def generate_vars_for_templates(self, players: list) -> dict:
            # From Player
            players_vars_list = []
            for p in players:
                players_vars_dict = dict(
                    var1 = self.format_number(p.var1),
                    var2 = self.format_money(p.var2),
                    )
                players_vars_list.append(players_vars_dict)
            
            return dict(
                players_vars_list = players_vars_list,
                b = self.format_number(self.b), # For b defined in this class (Group)
                c = self.format_number(self.subsession.c), # For c defined in Subsession class
            )
            
If I want to access to the var1 on the template, I call {{ players_vars_list.0.var1 }} for player 1 and it works, but that is showing me the var1 for the player 1 in all cases, also on player 2 screen.

My question is, how can I make the display in templates reactive to who is the player and show those var1, var2 for each of player screens? Without formatting I could simply type {{ player.var1 }} that showed the var1 reactive to each player but now it does not seem to work {{ players_vars_list.player.var1 }}. Any ideas? Many thanks.

#4 by kikenc49

Ok solved! I simply defined my generate_vars_for_templates(player: Player) outside the class Group. Basically mirroring the js_vars logic ;)

Write a reply

Set forum username