diff --git a/app/scodoc/sco_groups.py b/app/scodoc/sco_groups.py
index 8e834b2312da223225cb64c5c686afb9259ea253..80d8e02c658ac7419c8b75342a8800a80e1aca55 100644
--- a/app/scodoc/sco_groups.py
+++ b/app/scodoc/sco_groups.py
@@ -413,8 +413,15 @@ def formsemestre_get_etud_groupnames(formsemestre_id, attr="group_name"):
     return R
 
 
-def etud_add_group_infos(etud, formsemestre_id, sep=" "):
-    """Add informations on partitions and group memberships to etud (a dict with an etudid)"""
+def etud_add_group_infos(etud, formsemestre_id, sep=" ", only_to_show=False):
+    """Add informations on partitions and group memberships to etud
+    (a dict with an etudid)
+    If only_to_show, restrict to partions such that show_in_lists is True.
+
+    etud['partitions'] = { partition_id : group + partition_name }
+    etud['groupes'] = "TDB, Gr2, TPB1"
+    etud['partitionsgroupes'] = "Groupes TD:TDB, Groupes TP:Gr2 (...)"
+    """
     etud[
         "partitions"
     ] = collections.OrderedDict()  # partition_id : group + partition_name
@@ -423,11 +430,14 @@ def etud_add_group_infos(etud, formsemestre_id, sep=" "):
         return etud
 
     infos = ndb.SimpleDictFetch(
-        """SELECT p.partition_name, g.*, g.id AS group_id
+        """SELECT p.partition_name, p.show_in_lists, g.*, g.id AS group_id
         FROM group_descr g, partition p, group_membership gm WHERE gm.etudid=%(etudid)s
         and gm.group_id = g.id
         and g.partition_id = p.id
         and p.formsemestre_id = %(formsemestre_id)s
+        """
+        + (" and (p.show_in_lists is True) " if only_to_show else "")
+        + """
         ORDER BY p.numero
         """,
         {"etudid": etud["etudid"], "formsemestre_id": formsemestre_id},
diff --git a/app/scodoc/sco_page_etud.py b/app/scodoc/sco_page_etud.py
index 3a99d2232a91f0312f01f1dfc11e6451ae06fbaf..2631ef45c4f0525de57f2eac9d3cfc0884d44c78 100644
--- a/app/scodoc/sco_page_etud.py
+++ b/app/scodoc/sco_page_etud.py
@@ -153,14 +153,14 @@ def ficheEtud(etudid=None):
         try:  # pour les bookmarks avec d'anciens ids...
             etudid = int(etudid)
         except ValueError:
-            raise ScoValueError("id invalide !")
+            raise ScoValueError("id invalide !") from ValueError
         # la sidebar est differente s'il y a ou pas un etudid
         # voir html_sidebar.sidebar()
         g.etudid = etudid
     args = make_etud_args(etudid=etudid)
     etuds = sco_etud.etudident_list(cnx, args)
     if not etuds:
-        log("ficheEtud: etudid=%s request.args=%s" % (etudid, request.args))
+        log(f"ficheEtud: etudid={etudid!r} request.args={request.args!r}")
         raise ScoValueError("Etudiant inexistant !")
     etud = etuds[0]
     etudid = etud["etudid"]
@@ -173,7 +173,7 @@ def ficheEtud(etudid=None):
     if info["lieu_naissance"]:
         info["info_naissance"] += " à " + info["lieu_naissance"]
     if info["dept_naissance"]:
-        info["info_naissance"] += " (%s)" % info["dept_naissance"]
+        info["info_naissance"] += f" ({info['dept_naissance']})"
     info["etudfoto"] = sco_photos.etud_photo_html(etud)
     if (
         (not info["domicile"])
@@ -205,7 +205,7 @@ def ficheEtud(etudid=None):
         )
     else:
         info["emaillink"] = "<em>(pas d'adresse e-mail)</em>"
-    # champs dependant des permissions
+    # Champ dépendant des permissions:
     if authuser.has_permission(Permission.ScoEtudChangeAdr):
         info["modifadresse"] = (
             '<a class="stdlink" href="formChangeCoordonnees?etudid=%s">modifier adresse</a>'
@@ -216,9 +216,10 @@ def ficheEtud(etudid=None):
 
     # Groupes:
     sco_groups.etud_add_group_infos(
-        info, info["cursem"]["formsemestre_id"] if info["cursem"] else None
+        info,
+        info["cursem"]["formsemestre_id"] if info["cursem"] else None,
+        only_to_show=True,
     )
-
     # Parcours de l'étudiant
     if info["sems"]:
         info["last_formsemestre_id"] = info["sems"][0]["formsemestre_id"]
@@ -235,15 +236,28 @@ def ficheEtud(etudid=None):
             )
             grlink = '<span class="fontred">%s</span>' % descr["situation"]
         else:
-            group = sco_groups.get_etud_main_group(etudid, sem["formsemestre_id"])
-            if group["partition_name"]:
-                gr_name = group["group_name"]
-            else:
-                gr_name = "tous"
-            grlink = (
-                '<a class="discretelink" href="groups_view?group_ids=%s" title="Liste du groupe">groupe %s</a>'
-                % (group["group_id"], gr_name)
+            e = {"etudid": etudid}
+            sco_groups.etud_add_group_infos(
+                e,
+                sem["formsemestre_id"],
+                only_to_show=True,
             )
+
+            grlinks = []
+            for partition in e["partitions"].values():
+                if partition["partition_name"]:
+                    gr_name = partition["group_name"]
+                else:
+                    gr_name = "tous"
+
+                grlinks.append(
+                    f"""<a class="discretelink" href="{
+                    url_for('scolar.groups_view', 
+                    scodoc_dept=g.scodoc_dept, group_ids=partition['group_id'])
+                }" title="Liste du groupe {gr_name}">{gr_name}</a>
+                """
+                )
+            grlink = ", ".join(grlinks)
         # infos ajoutées au semestre dans le parcours (groupe, menu)
         menu = _menuScolarite(authuser, sem, etudid)
         if menu:
@@ -296,17 +310,18 @@ def ficheEtud(etudid=None):
         if not sco_permissions_check.can_suppress_annotation(a["id"]):
             a["dellink"] = ""
         else:
-            a[
-                "dellink"
-            ] = '<td class="annodel"><a href="doSuppressAnnotation?etudid=%s&annotation_id=%s">%s</a></td>' % (
-                etudid,
-                a["id"],
-                scu.icontag(
-                    "delete_img",
-                    border="0",
-                    alt="suppress",
-                    title="Supprimer cette annotation",
-                ),
+            a["dellink"] = (
+                '<td class="annodel"><a href="doSuppressAnnotation?etudid=%s&annotation_id=%s">%s</a></td>'
+                % (
+                    etudid,
+                    a["id"],
+                    scu.icontag(
+                        "delete_img",
+                        border="0",
+                        alt="suppress",
+                        title="Supprimer cette annotation",
+                    ),
+                )
             )
         author = sco_users.user_info(a["author"])
         alist.append(
@@ -422,9 +437,11 @@ def ficheEtud(etudid=None):
 
     #
     if info["groupes"].strip():
-        info["groupes_row"] = (
-            '<tr><td class="fichetitre2">Groupe :</td><td>%(groupes)s</td></tr>' % info
-        )
+        info[
+            "groupes_row"
+        ] = f"""<tr>
+        <td class="fichetitre2">Groupes :</td><td>{info['groupes']}</td>
+        </tr>"""
     else:
         info["groupes_row"] = ""
     info["menus_etud"] = menus_etud(etudid)