Objectif : Utilise la balise "regroup" en filtrant sur une clé étrangère

Modèle :

Soit le modèle suivant :

"""
Technicat skills
"""
 
class DomainTechSkill(models.Model):
     name = models.CharField('Domaine de compétence technique', Maxlength=100, core=True)
 
class Techskill(models.Model):
     who = models.ForeignKey(User, verbose_name='Personne',)
     name = models.CharField('Compétences techniques', maxlength=100, core=True)
     domain = models.ForeignKey(DomainTechSkill, verbose_name='Domaine de compétences techniques',)
 
class Usertechskill(models.Model):
     who = models.ForeignKey(User, verbose_name='Personne',)
     name = models.ManyToManyField(Techskill, verbose_name='Compétence technique', filter_interface=models.HORIZONTAL, blank=True)

L'idée est de faire d'une part TechSkill <=>DomainTechSkill et d'autre part User <=> TechSkill. Ensuite au niveau de la restitution, on veut lister les compétences techniques d'un utilisateur en les regroupant par "DomainTechSkill".

Vue :

avec la vue suivante (extrait) :

def cv_detail(request, firstname, lastname):
     user = User.objects.get(first_name=firstname, last_name=lastname)
     user_techskill = user.usertechskill_set.all()
     return render_to_response('cv/cv_detail.html', {'user_techskill': user_techskill, })

Template :

et le template suivant (extrait) :

                 {# -- technical skills -- #}
                 {% if user_techskill %}
                 <p>Comp&eacute;tences techniques :</p>
                 {% for techskill in user_techskill %}
                 {% regroup techskill.name.all|dictsort:"domain" by domain as grouped %}
                 <ul>
                          {% for group in grouped %}
                                 <li> {{ group.grouper }} :
                                         {% for item in group.list %}
                                                 {{ item.name }}{% if forloop.last %}.{% else %},{% endif %}
                                         {% endfor %}
                                 </li>
                          {% endfor %}
                 </ul>
                 {% endfor %}
                 {% endif %}

Jeux de données :

Imaginons que j'ai alors rentré les couples de valeur suivants (Compétence techniques / Domaine Technique) :

  • HTML / Web
  • CSS / Web
  • Apache / Serveur
  • Portail / Système d'information
  • Bind / Serveur
  • CMS / Système d'information

Ce qui est souhaité :

  • Serveur : Apache, Bind
  • Système d'information : CMS, Portail
  • Web : HTML, CSS

Ce qui est parfois obtenu (comme n'importe quelle autre combinaison de ces valeurs, ce qui nous permet d'avoir la bonne de temps à autre)

  • Serveur : Apache
  • Système d'information : CMS, Portail
  • Serveur : Bind
  • Web : HTML, CSS

Solution pour avoir la bonne combinaison de façon systématique :

La solution consiste dès lors à ajouter le nom de l'attribut (ex : domain.name) ou de filtrer par un id (ex : domain.id)

                 {% regroup techskill.name.all|dictsort:"domain.name" by domain as grouped %}

Et là, vous avez systématiquement le résultat souhaité (seul l'ordre des compétences peut varier sur une même ligne)

Merci à Samuel pour m'avoir indiqué cette capacité.