Question

I have model with ManyToManyField:

class Action(models.Model):
    title = models.CharField('title', max_length=160)
    countries = models.ManyToManyField('Country', null=True, blank=True)

class Country(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=255, blank=True)

Every action has an url to page with description. Every country has an icon with flag. Action may have 2 or more countries. So output should be like this:

  1. Country 1, County 2
    • Action
    • Action
    • Action
  2. Country 3, Country 4
    • Action
  3. Country 1
    • Action
    • Action
  4. Country 3
    • Action

I don't know how to resolve the problem. Tag {% regroup %} doesn't work correctly because it groups only by first country in each action.

Was it helpful?

Solution

I think that you need to write your own regrouping algorithm. If it used only once in all application you can create it in view:

regrouped = {}
actions = Action.objects.all()
# be careful this implementation creates large amount of sql queries.
# you need to optimize it or cache it!
for action in actions:
    country_key = '_'.join([country.pk for country in action.countries.all()])
    if not country_key in regrouped:
        regrouped[country_key] = {'countries': action.countries.all(), 'actions': []}
    regrouped[country_key]['actions'].append(action)

And in template:

{% for key, item in regrouped.items %}
Countries: {% for country in item.countries %}{{ country }};{% endfor %}
Actions: {% for action in item.actions %}{{ action }};{% endfor %}
{% endfor %}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top