Filtrer les alertes en fonction des groupes

N'avoir que les alertes des groupes dont on fait partie.

a marqué ce sujet comme résolu.

Salut à tous,

J'ai parcouru le code de Zeste de Savoir (mes félicitations, il est clair et lisible) à la recherche de comment faire en sorte de n'avoir, dans le menu des alertes, que celles du groupe associé. Par exemple, en tant que membre du staff, je vois les alertes levées par les administrateurs mais je ne peux pas y accéder (ce qui est normal).

De mes recherches, j'ai trouvé la fonction la fonction alerts_list dans ce fichier (lignes 143 et 144).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@register.filter(name='alerts_list')
def alerts_list(user):
    total = []
    alerts = Alert.objects.select_related('author', 'comment').all().order_by('-pubdate')[:10]
    nb_alerts = Alert.objects.count()
    for alert in alerts:
        if alert.scope == Alert.FORUM:
            post = Post.objects.select_related('topic').get(pk=alert.comment.pk)
            total.append({'title': post.topic.title,
                          'url': post.get_absolute_url(),
                          'pubdate': alert.pubdate,
                          'author': alert.author,
                          'text': alert.text})

        elif alert.scope == Alert.CONTENT:
            note = ContentReaction.objects.select_related('related_content').get(pk=alert.comment.pk)
            total.append({'title': note.related_content.title,
                          'url': note.get_absolute_url(),
                          'pubdate': alert.pubdate,
                          'author': alert.author,
                          'text': alert.text})

    return {'alerts': total, 'nb_alerts': nb_alerts}

De plus, en examinant ce fichier, notamment la fonction settings_promote (à partir de la ligne 956), on sait comment récupérer les groupes auxquels appartient un membre.

1
usergroups = user.groups.all()

Du coup, je réfléchis à comment modifier le code pour se faire, mais j'ai besoin d'aide ; c'est ma première plongée dans le code, donc je ne suis pas sûr de ce que je fais.. Est-ce que c'est bien dans la fonction alerts_list qu'il faut faire les modifications ? Et est-ce que quelqu'un qui a un environnement de test installé pourra m'aider à faire les tests (pas possible d'en installer un avant mercredi soir au plus tôt) ?

Merci d'avance à tous,

La staffeuse gantée

Ah oui d'accord. Les alertes ne sont pas spécialement destinées à tel ou tel groupe, c'est simplement que tu n'as pas les droits pour te rendre sur les sujets sur lesquelles porte les alertes.

Alors pour répondre à tes questions :

Est-ce que c'est bien dans la fonction alerts_list qu'il faut faire les modifications ?

C'est l'une des solutions et sans doute la plus simple, donc oui. Il faudrait complexifier un poil les requêtes en base pour exclure les alertes qui porte sur des messages appartenant à un forum dans lequel tu n'as pas les droits de te rendre.

Et est-ce que quelqu'un qui a un environnement de test installé pourra m'aider à faire les tests (pas possible d'en installer un avant mercredi soir au plus tôt) ?

Sauf si tu es certain du premier coup de ta requête en base, je ne pense pas que c'est une bonne idée de passer par un contributeur régulier. Nous ne sommes pas à quelques jours près, nous pouvons attendre mercredi que tu prennes le temps d'installer l'environnement pour faire tes tests et on espère une première PR ! :)

J'ai continué à réfléchir, mais je comme je suis débutant en Python, et encore plus dans l'utilisation de Django, je me pose une question : peut-on, dans la ligne suivante, remplacer .all() par .get(/*des paramètres*/) ?

1
alerts = Alert.objects.select_related('author', 'comment').all().order_by('-pubdate')[:10]

Cette ligne est la ligne 146 du fichier zds-site/zds/utils/templatetags/interventions.py.

Non, parce que get(...) est utilisé pour te renvoyer un et un seul objet lié à tes paramètres (et devrait lancer une exception si tu as plusieurs résultats). Par contre, tu peux utiliser la méthode filter(...) qui va te renvoyer la liste de tes alertes suivant le filtre que tu appliqueras.

Tu auras donc quelque chose comme ceci :

1
alerts = Alert.objects.filter(...).select_related('author', 'comment').all().order_by('-pubdate')[:10]

Ok, merci pour la réponse. Je progresse. Voilà la façon de faire que je compte implémenter.

  • On récupère l'URL de l'alerte pour savoir dans quel forum on est.
  • On utilise la fonction can_read (ligne 151) du fichier zds-site/zds/forum/models.py pour savoir si on peut accéder ou non à ce forum.
  • Si non, on exclut l'alerte des alertes à afficher.

Et si j'ai bien compris les commentaire, l'URL d'un commentaire, et donc d'une alerte, se récupère avec get_comment_subclass ?

  • On récupère l'URL de l'alerte pour savoir dans quel forum on est.

Pour pouvoir utiliser la fonction can_read, il faut une instance d'un Forum. J'aurais voulu pouvoir faire une jointure un peu complexe pour récupérer le forum directement à partir de la requête existante sur Alert mais ça ne semble pas possible. Nous ne disposons pas des informations nécessaires.

Du coup, il faudrait faire une requête en base supplémentaire pour récupérer le forum ou le contenu (tutoriel ou article) qui contient le message alerté.

  • On utilise la fonction can_read (ligne 151) du fichier zds-site/zds/forum/models.py pour savoir si on peut accéder ou non à ce forum.

A partir de cet objet et si ton message provient des forums, il faut vérifier que tu as bien les droits avec can_read. Même s'il est possible de signaler un message d'un contenu, il n'est pas possible que tu n'ai pas accès à ces contenus. On vérifie donc simplement si tu es dans un forum.

Si non, on exclut l'alerte des alertes à afficher.

Toutafé. :)

Et si j'ai bien compris les commentaire, l'URL d'un commentaire, et donc d'une alerte, se récupère avec get_comment_subclass ?

Oh, je n'avais pas connaissance de cette fonction. Elle pourrait être bien utile puisque tu passerais d'une instance Comment à l'instance Post qui elle contient l'information de son topic et donc de son forum.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte