Caleb Peter
Caleb Peter

Reputation: 3

How to shuffle/randomize list items after regrouping them using Django's regroup template tag

I have this list presented in dictionaries:

cities = [
    {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
    {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
    {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
    {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
    {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
]

I have regrouped the list using Django's regroup tag:

{% regroup cities by country as country_list %}

<ul>
{% for country in country_list %}
    <li>{{ country.grouper }}
    <ul>
        {% for city in country.list %}
          <li>{{ city.name }}: {{ city.population }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

This is the template output:

India
Mumbai: 19,000,000
Calcutta: 15,000,000

USA
New York: 20,000,000
Chicago: 7,000,000

Japan
Tokyo: 33,000,000

That is pretty much of what I intended to do. I now want to randomly shuffle items under each country list. For example, under USA, I want to shuffle New York and Chicago so that the display is not biased to the viewer. When I use shuffle(cities) in my views, I get an output like this:

India
Mumbai: 19,000,000

USA
New York: 20,000,000

India
Calcutta: 15,000,000

USA
Chicago: 7,000,000

Japan
Tokyo: 33,000,000

I basically want to shuffle cities while remaining intact under their countries. I dont want the order of countries to change but only the order of cities to change randomly. I am stuck on what to do from here. I tried a custom template simple_tag but still things didn't work.

Upvotes: 0

Views: 232

Answers (1)

Jafoor
Jafoor

Reputation: 735

>>> cities = [
     {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
     {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
     {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
     {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
     {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
 ]
>>> import random
>>> random.shuffle(cities)
>>> print(cities)
[{'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
{'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'}, 
{'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
{'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'}, 
{'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'}]

So, before rendering data into template shuffle list there.

import random
random.shuffle(cities)

Don't use the code of the upper part.

But it will change your country's order. So you can use custom template tag for shuffle.

Firstly create a folder named templatetags. then create a file name __init__.py. it would be empty. and create another file named shuffle.py. there save the bellow code.

# YourApp/templatetags/shuffle.py
import random
from django import template
register = template.Library()

@register.filter
def shuffle(arg):
    tmp = list(arg)[:]
    random.shuffle(tmp)
    return tmp

Project Directory:

-Your_App
--templatetags
---__init__.py
---shuffle.py

Now in your template:

{% regroup cities by country as country_list %}

<ul>
{% for country in country_list %}
    <li>{{ country.grouper }}
    <ul>
        {% for city in country.list|shuffle %}
          <li>{{ city.name }}: {{ city.population }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

Upvotes: 3

Related Questions