3

I am building a betting app where users can bet on different games. I want to show users' bets for different games in a table such as one as below:

game #   |   user 1   |   user 2   |   user 3

game 1  |   XXXX    |   XXXX    |   XXXX

game 2  |   XXXX    |   XXXX    |   XXXX

game 3  |   XXXX    |   XXXX    |   XXXX

...

here's my view

users = User.objects.all()
games = Game.objects.all()
bets = Bet.objects.all()

user_bets = [[] for i in range(len(games))]

for i, game in enumerate(games):
    game_bets = bets.filter(game=game)
    for usr in users:
        user_bet = game_bets.filter(user=usr)[0]
        user_bets[i].append(user_bet)

data = {'games', games, 'users', users, 'user_bets': user_bets}
return render(request, 'bets.html', data)

But I don't know how to fill in the table using the 2d array user_bets. Any suggestions? Or if I'm doing the whole thing wrong any best practice to pass such data to template in Django?

Cheers

Martin Tournoij
  • 26,737
  • 24
  • 105
  • 146
Blademaster
  • 324
  • 2
  • 15
  • An easy way to do this is with a custom filter as [shown here](https://stackoverflow.com/a/10700142). – Jedi Jun 21 '17 at 22:05

3 Answers3

5

Passing Multi-dimensional arrays to templates in django is not straight forward. I've been working on this problem for a while, so I know your question is old, but for the betterment of django society, here's what I've finally worked out...

users = User.objects.all()
games = Game.objects.all()
bets = Bet.objects.all()

user_bets=[]
game_title=[]

for i, game in enumerate(games):
    game_titles = [game.title]
    game_bets = bets.filter(game=game)
    for usr in users:
        user_bet = game_bets.filter(user=usr)[0]
        user_bets[i][usr.id]=user_bet
data = {'game_titles', game_titles 'users', users, 'user_bets': user_bets}
return render(request, 'bets.html', data)

You then want to define two template filters, which for ease can live in your views.py

@register.filter
def index(List, i):
    return List[int(i)]

@register.filter
def entry_num_array(List):
    return range(len(List))

Then in your template

{% for bet in user_bets %}
{{ game_titles|index:forloop.counter0}}:
    {% for counter in entry|entry_num_array %}
        {{entry|index:counter}}|
    {% endfor %}
    <br>                
{% endfor %}
talkingtoaj
  • 848
  • 8
  • 27
1

For those who are looking for accessing a standard 2D array,you can use nested loop. code is below

views.py

    content={'f':[[1,2,3,4],[4,5,6,7]]}
    return render(request,'index.html',content)

index.html

{% for array in f %}
{% for content in array %}
<h1>{{content}}</h1>
{% endfor %}
{% endfor %}
TheGuardener
  • 361
  • 5
  • 11
0

For those who are looking for accessing a combination of Lists,Touples, etc. you can programm a nested loop as mentioned above by "The Guardener" and builtins if tags:

some_list={
           1:{('a','Answer1'),('b','Answerb')},
           2:{'Something':'else'},
           3:{'Something':'else'}
          }

Template: index.html:

{% for nested_list in some_list %}
{% for list_element in nested_list %}
    {% if list_element.0 == 'a' %}
      some_list[nested_list[list_element[0]=='a']]]: {{ list_element.1 }} # Answer1 
    {% endif %}
{% endfor %}
{% endfor %}

I couldn't test this example only parts of it.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Zykrates
  • 61
  • 4