internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: zestedesavoir/zds-site

Issue:
Galerie non renommée si le tuto change de nom
Via [mathiasmch, sur le forum](http://zestedesavoir.com/membres/voir/mathiasmch/) : 

> Lorsque l'on modifie le nom d'un tutoriel, celui de sa galerie n'est pas mis à jour. Je ne sais pas si ça peut avoir des conséquences par la suite…



Discussion:
Je peux m'en occuper.

Je t'en prie. Fait quand même gaffe que @ArnaudCalmettes n'as pas donné de _milestone_ pour cette issue, donc demande son avis avant.

Je suis dessus.


Resolving patch:
diff --git a/zds/tutorial/views.py b/zds/tutorial/views.py
--- a/zds/tutorial/views.py
+++ b/zds/tutorial/views.py
@@ -983,6 +983,13 @@ def edit_tutorial(request):
 
             tutorial.update = datetime.now()
 
+            # MAJ gallery
+
+            gal = Gallery.objects.filter(pk=tutorial.gallery.pk)
+            gal.update(title=data["title"])
+            gal.update(slug=slugify(data["title"]))
+            gal.update(update=datetime.now())
+
             # MAJ image
 
             if "image" in request.FILES:


Test patch:
diff --git a/zds/tutorial/tests.py b/zds/tutorial/tests.py
--- a/zds/tutorial/tests.py
+++ b/zds/tutorial/tests.py
@@ -1363,6 +1363,30 @@ def test_workflow_beta_tuto(self) :
             self.client.get(url).status_code,
             200)
 
+    def test_gallery_tuto_change_name(self):
+        """
+        Test if the gallery attached to a tutorial change its name when the tuto
+        has the name changed.
+        """
+
+        newtitle = u"The New Title"
+        response = self.client.post(
+            reverse('zds.tutorial.views.edit_tutorial') + '?tutoriel={}'.format(self.bigtuto.pk),
+            {
+                'title': newtitle,
+                'subcategory': self.subcat.pk,
+                'introduction': self.bigtuto.introduction,
+                'description': self.bigtuto.description,
+                'conclusion': self.bigtuto.conclusion,
+            },
+            follow=True)
+
+        tuto = Tutorial.objects.filter(pk=self.bigtuto.pk).first()
+        self.assertEqual(tuto.title, newtitle)
+        self.assertEqual(tuto.gallery.title, tuto.title)
+        self.assertEqual(tuto.gallery.slug, tuto.slug)
+
+
     def tearDown(self):
         if os.path.isdir(settings.REPO_PATH):
             shutil.rmtree(settings.REPO_PATH)
Repository: zestedesavoir/zds-site

Issue:
[Ortho] Correction mineure dans le message d'édition
Il faudrait remplacer "Edité" par "Édité" dans cette ligne : 

=> https://github.com/zestedesavoir/zds-site/blob/24161830d639169c7092c83e7f75d20c0c5f1ba9/templates/misc/message.part.html#L178



Discussion:
Est-ce qu'on peut autoriser **exceptionnellement** la modif' direct sur la branche master ? C'est un peu pénible de faire une PR **juste pour une lettre**...

(si on me repond "nan!" je comprend aussi)

On m'a déjà répondu "non" par le passé, donc je te le dis à mon tour : non ! :D 

Ce n'est pas le seul, j'avais reporté plusieurs problèmes d'accent sur le forum. Autant grouper.

Qui se lance pour une PR "orthographe" ?

Si on me liste les fautes d'ici ce soir je peux le faire en rentrant chez moi (IRC a partir de 16h15) (mais me demandez pas non plus d'aller relire les xx pages du sujet "Les petits pixels")


Resolving patch:
diff --git a/zds/member/forms.py b/zds/member/forms.py
--- a/zds/member/forms.py
+++ b/zds/member/forms.py
@@ -258,7 +258,7 @@ def __init__(self, *args, **kwargs):
             Field('avatar_url'),
             Field('sign'),
             ButtonHolder(
-                StrictButton('Editer le profil', type='submit'),
+                StrictButton('Éditer le profil', type='submit'),
                 HTML('<a class="btn btn-cancel" href="/">Annuler</a>'),
             ))
 


Test patch:
Repository: zestedesavoir/zds-site

Issue:
Erreur 500 lors de consultation de l'historique d'un article
J'ai une erreur 500 sur la consultation de l'historique des versions d'un article en redaction. Arius a eu le problème aussi.

Le bug semble être arrivé avec la 1.4



Discussion:
Il semblerai que c'est le `{% crispy formJs %}` qui fait planter le truc. 

D'ailleurs @firm1 c'est toi qui l'a introduit. Une raison particulière ?


Resolving patch:
diff --git a/zds/article/views.py b/zds/article/views.py
--- a/zds/article/views.py
+++ b/zds/article/views.py
@@ -949,8 +949,10 @@ def history(request, article_pk, article_slug):
     logs = repo.head.reference.log()
     logs = sorted(logs, key=attrgetter('time'), reverse=True)
 
+    form_js = ActivJsForm(initial={"js_support": article.js_support})
+
     return render(request, 'article/member/history.html', {
-        'article': article, 'logs': logs
+        'article': article, 'logs': logs, 'formJs': form_js
     })
 
 # Reactions at an article.


Test patch:
Repository: zestedesavoir/zds-site

Issue:
Lorsqu'on enlève un sujet des post-it le message est faux
On a le message suivant qui est faux : 

> Le sujet FOO est désormais épinglé.



Discussion:

Resolving patch:
diff --git a/zds/forum/views.py b/zds/forum/views.py
--- a/zds/forum/views.py
+++ b/zds/forum/views.py
@@ -415,11 +415,13 @@ def edit(request):
             messages.success(request,
                              u"Le sujet {0} est désormais verrouillé."
                              .format(g_topic.title))
-        if "sticky" in data:
-            g_topic.is_sticky = data["sticky"] == "true"
-            messages.success(request,
-                             u"Le sujet {0} est désormais épinglé."
-                             .format(g_topic.title))
+        if 'sticky' in data:
+            if data['sticky'] == 'true':
+                g_topic.is_sticky = True
+                messages.success(request, _(u'Le sujet « {0} » est désormais épinglé.').format(g_topic.title))
+            else:
+                g_topic.is_sticky = False
+                messages.success(request, _(u'Le sujet « {0} » n\'est désormais plus épinglé.').format(g_topic.title))
         if "move" in data:
             try:
                 forum_pk = int(request.POST["move_target"])


Test patch:
Repository: zestedesavoir/zds-site

Issue:
La licence est absente lors de la visualisation d'une partie du tutoriel
Quand on navigue partout dans un tutoriel, on a normalement la licence de celui en haut à droite. Sauf lorsqu'on regarde une partie ([celle-ci](http://beta.zestedesavoir.com/tutoriels/335/creez-des-applications-pour-android/425/annexes/) par exemple).



Discussion:

Resolving patch:
diff --git a/zds/utils/templatetags/topbar.py b/zds/utils/templatetags/topbar.py
--- a/zds/utils/templatetags/topbar.py
+++ b/zds/utils/templatetags/topbar.py
@@ -1,9 +1,12 @@
 # coding: utf-8
 
 from collections import OrderedDict
+import itertools
+
 from django import template
 from django.conf import settings
-import itertools
+
+from zds.article.models import Article
 from zds.forum.models import Forum, Topic
 from zds.tutorial.models import Tutorial
 from zds.utils.models import CategorySubCategory, Tag
@@ -91,6 +94,37 @@ def top_categories_tuto(user):
     return cats
 
 
+@register.filter('top_categories_article')
+def top_categories_article(user):
+    """
+        Get all the categories and their related subcategories
+        associed with an existing articles. The result is sorted
+        by alphabetic order.
+    """
+
+    # Ordered dict is use to keep order
+    cats = OrderedDict()
+
+    subcats_articles = Article.objects.values('subcategory').filter(sha_public__isnull=False).all()
+    catsubcats = CategorySubCategory.objects \
+        .filter(is_main=True)\
+        .filter(subcategory__in=subcats_articles)\
+        .order_by('category__position', 'subcategory__title')\
+        .select_related('subcategory', 'category')\
+        .values('category__title', 'subcategory__title', 'subcategory__slug')\
+        .all()
+
+    for csc in catsubcats:
+        key = csc['category__title']
+
+        if key in cats:
+            cats[key].append((csc['subcategory__title'], csc['subcategory__slug']))
+        else:
+            cats[key] = [(csc['subcategory__title'], csc['subcategory__slug'])]
+
+    return cats
+
+
 @register.filter('auth_forum')
 def auth_forum(forum, user):
     return forum.can_read(user)


Test patch:
Repository: zestedesavoir/zds-site

Issue:
Les adresses emails des pages de contacts sont capturables par les bots
Autant pour afficher le mail d'un membre sur sa page profil, on utilise un filtre qui nous permet de masquer l'adresse email aux bots, autant les pour les adresses mails de la page contact, cgu, et asso, on a pas de filtre.

Il serait bon d'appliquer le même filtre (email_obfuscator) sur tous les adresses emails affichés.



Discussion:
Je suis dessus mais actuellement on ne peut pas ajouter un sojet au mailto. 3 options : 
- On supprime le sujet pour le template `pages/template.html`
- J'ajoute un templatetag et je crée une PR sur le projet
- On vire la dépendance et on inclue le code dans nos templatetag vu qu'il est extrêmement simple (https://github.com/morninj/django-email-obfuscator/blob/master/email_obfuscator/templatetags/email_obfuscator.py).

J'ai une préférence pour la 3ème mais je préfère avoir plusieurs avis.

Je partirais sur la troisième solution, faut aussi voir pour l'attribut target="_top".

D'accord pour la 3ème.


Resolving patch:
diff --git a/zds/settings.py b/zds/settings.py
--- a/zds/settings.py
+++ b/zds/settings.py
@@ -166,7 +166,6 @@
     'easy_thumbnails.optimize',
     'south',
     'crispy_forms',
-    'email_obfuscator',
     'haystack',
     'munin',
     'social.apps.django_app.default',
diff --git a/zds/utils/templatetags/email_obfuscator.py b/zds/utils/templatetags/email_obfuscator.py
new file mode 100644
--- /dev/null
+++ b/zds/utils/templatetags/email_obfuscator.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# Mainly based on django-email-obfuscator (https://github.com/morninj/django-email-obfuscator - MIT Licence)
+# https://github.com/morninj/django-email-obfuscator/blob/master/email_obfuscator/templatetags/email_obfuscator.py
+
+from django import template
+from django.template.defaultfilters import stringfilter
+from django.utils.safestring import mark_safe
+
+register = template.Library()
+
+
+def obfuscate_string(value):
+    return ''.join(['&#{0:s};'.format(str(ord(char))) for char in value])
+
+
+@register.filter
+@stringfilter
+def obfuscate(value):
+    return mark_safe(obfuscate_string(value))
+
+
+@register.filter
+@stringfilter
+def obfuscate_mailto(value, text=None):
+    mail = obfuscate_string(value)
+
+    if text:
+        link_text = text
+    else:
+        link_text = mail
+
+    return mark_safe('<a href="{0:s}{1:s}">{2:s}</a>'.format(
+        obfuscate_string('mailto:'), mail, link_text))
+
+
+@register.filter
+@stringfilter
+def obfuscate_mailto_top_subject(value, subject=None):
+    mail = obfuscate_string(value)
+
+    if subject:
+        txt = obfuscate_string('?Subject={0}'.format(subject))
+    else:
+        txt = ''
+
+    return mark_safe('<a href="{0}{1}{2}" target="_top">{3}</a>'.format(obfuscate_string('mailto:'), mail, txt, mail))


Test patch:
Repository: zestedesavoir/zds-site

Issue:
Un utilisateur peut s'écrire à lui même
Testé en préprod.

Scénario : 
- Je vais dans l'interface des messages
- Dans les destinaites, je renseigne la chaine suivante (contenu entre guillemets) " , ".
- Le MP m'est envoyé à moi tout seul.



Discussion:

Resolving patch:
diff --git a/zds/mp/forms.py b/zds/mp/forms.py
--- a/zds/mp/forms.py
+++ b/zds/mp/forms.py
@@ -76,7 +76,8 @@ def clean(self):
         if participants is not None and participants.strip() != '':
             receivers = participants.strip().split(',')
             for receiver in receivers:
-                if User.objects.filter(username__exact=receiver.strip()).count() == 0 and receiver.strip() != '':
+                if User.objects.filter(username__exact=receiver.strip()).count() == 0 and receiver.strip() != '' \
+                        or receiver.strip() == '':
                     self._errors['participants'] = self.error_class(
                         [_(u'Un des participants saisi est introuvable')])
                 elif receiver.strip().lower() == self.username.lower():


Test patch:
diff --git a/zds/mp/tests/tests_forms.py b/zds/mp/tests/tests_forms.py
--- a/zds/mp/tests/tests_forms.py
+++ b/zds/mp/tests/tests_forms.py
@@ -123,6 +123,17 @@ def test_invalid_topic_form_self_message_2(self):
         form = PrivateTopicForm(self.profile1.user.username, data=data)
         self.assertFalse(form.is_valid())
 
+    def test_invalid_topic_form_comma(self):
+        """ Cas when participants is only a comma """
+        data = {
+            'participants': ',',
+            'title': 'Test title',
+            'subtitle': 'Test subtitle',
+            'text': 'Test text'
+        }
+        form = PrivateTopicForm(self.profile1.user.username, data=data)
+        self.assertFalse(form.is_valid())
+
 
 class PrivatePostFormTest(TestCase):
Repository: zestedesavoir/zds-site

Issue:
Progdupeu.pl a changé de nom de domaine et d'hébergement Git
Comme on est un _fork_ de progdupeu.pl, on se retrouve avec quelques références cassées depuis [les récents changements sur progdupeu.pl](https://pdp.microjoe.org/forums/sujet/882/a-propos-des-problemes-recents-de-domaine)

La PR arrive.



Discussion:

Resolving patch:
diff --git a/zds/settings.py b/zds/settings.py
--- a/zds/settings.py
+++ b/zds/settings.py
@@ -376,7 +376,7 @@
                 'code': u"GPL v3",
                 'url_license': u"http://www.gnu.org/licenses/gpl-3.0.html",
                 'provider_name': u"Progdupeupl",
-                'provider_url': u"http://progdupeu.pl",
+                'provider_url': u"http://pdp.microjoe.org",
             },
             'licence_info_title': u'http://zestedesavoir.com/tutoriels/281/le-droit-dauteur-creative-commons-et-les-lic'
                                   u'ences-sur-zeste-de-savoir/',


Test patch:
Repository: zestedesavoir/zds-site

Issue:
Plus de pagination dans la liste des membres
Url incriminée :  http://beta.zestedesavoir.com/membres/

On ne voit que 100 membres inscrit, alors qu'il y'en a plus.



Discussion:
Sera corrigé avec https://github.com/zestedesavoir/zds-site/pull/2228

Devrait être OK, mais j'attends quand même le test en QA avec un vrai environnement pour fermer ici.


Resolving patch:
diff --git a/zds/utils/paginator.py b/zds/utils/paginator.py
--- a/zds/utils/paginator.py
+++ b/zds/utils/paginator.py
@@ -17,7 +17,6 @@ def get_context_data(self, **kwargs):
         context_object_name = self.get_context_object_name(queryset)
         paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size)
         if page_size:
-            paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size)
             context = {
                 'paginator': paginator,
                 'page_obj': page,


Test patch:
Repository: zestedesavoir/zds-site

Issue:
Erreur 500 lors de la recherche d'un sujet
Url incriminée : `http://beta.zestedesavoir.com/forums/sujets/recherche/`

On ne devrait jamais avoir d'erreur 500



Discussion:
La page plante car il manque les paramètres.

Je m'en occupe.

@SpaceFox tu peux ajouter @A-312 au groupe des assignés ? Tout comme @Situphen 

Invitations envoyées (je pensais que c'était fait depuis longtemps pour @Situphen !)


Resolving patch:
diff --git a/zds/forum/views.py b/zds/forum/views.py
--- a/zds/forum/views.py
+++ b/zds/forum/views.py
@@ -1061,6 +1061,9 @@ def followed_topics(request):
 
 
 def complete_topic(request):
+    if not request.GET.get('q', None):
+        return HttpResponse("{}", content_type='application/json')
+
     sqs = SearchQuerySet().filter(content=AutoQuery(request.GET.get('q'))).order_by('-pubdate').all()
 
     suggestions = {}


Test patch:
Repository: zestedesavoir/zds-site

Issue:
Incohérence sur le nombre de messages d'un membre
Les 2 pages en questions : https://zestedesavoir.com/membres/voir/Iris13/ https://zestedesavoir.com/forums/messages/1927/.

On a 3 messages alors que aucun n'est affiché.



Discussion:
Chez moi c'est cohérent. Je pense que c'est parce que les 3 messages en question sont modérés, et que donc tu ne peux pas les voir sans avoir les droits staff.

Oui effectivement. Dans ce cas on doit changer le nombre de messages qu'un simple membre peut voir non ?

Si ça ne nécessite pas des requêtes dans une boucle, oui :)

Au pire, il suffit de rajouter pour les non-staff un message du genre :
"des messages modérés peuvent ne pas apparaître dans cette liste" ou un
truc du genre.

Le 10 février 2015 16:15, Laville Augustin notifications@github.com a
écrit :

> Oui effectivement. Dans ce cas on doit changer le nombre de messages qu'un
> simple membre peut voir non ?
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/zestedesavoir/zds-site/issues/2275#issuecomment-73715672
> .


Resolving patch:
diff --git a/zds/member/models.py b/zds/member/models.py
--- a/zds/member/models.py
+++ b/zds/member/models.py
@@ -133,6 +133,10 @@ def get_avatar_url(self):
 
     def get_post_count(self):
         """Number of messages posted."""
+        return Post.objects.filter(author__pk=self.user.pk, is_visible=True).count()
+
+    def get_post_count_as_staff(self):
+        """Number of messages posted (view as staff)."""
         return Post.objects.filter(author__pk=self.user.pk).count()
 
     def get_topic_count(self):


Test patch:
Repository: zestedesavoir/zds-site

Issue:
Absence de notification lorsqu'on nous ajoute à une conversation via MP
On m'a ajouté à une conversation via MP et je n'ai reçu aucune alerte avant le premier message posté. Ce serait cool d'avoir une notification (mail).



Discussion:

Resolving patch:
diff --git a/zds/mp/views.py b/zds/mp/views.py
--- a/zds/mp/views.py
+++ b/zds/mp/views.py
@@ -17,6 +17,7 @@
 from django.shortcuts import redirect, get_object_or_404, render, render_to_response
 from django.template import Context
 from django.template.loader import get_template
+from django.template.loader import render_to_string
 from django.views.decorators.http import require_POST
 from django.forms.util import ErrorList
 from django.core.exceptions import ObjectDoesNotExist
@@ -546,6 +547,25 @@ def add_participant(request):
             ptopic.participants.add(part)
             ptopic.save()
 
+            # send email
+            profile = part.profile
+            if profile.email_for_answer:
+                subject = u"{} - MP : {}".format(settings.ZDS_APP['site']['litteral_name'], ptopic.title)
+                from_email = u"{} <{}>".format(settings.ZDS_APP['site']['litteral_name'],
+                                               settings.ZDS_APP['site']['email_noreply'])
+                context = {
+                    'username': part.username,
+                    'url': settings.ZDS_APP['site']['url'] + ptopic.get_absolute_url(),
+                    'author': request.user.username,
+                    'site_name': settings.ZDS_APP['site']['litteral_name']
+                }
+                message_html = render_to_string('email/mp/new_participant.html', context)
+                message_txt = render_to_string('email/mp/new_participant.txt', context)
+
+                msg = EmailMultiAlternatives(subject, message_txt, from_email, [part.email])
+                msg.attach_alternative(message_html, "text/html")
+                msg.send()
+
             messages.success(
                 request,
                 _(u'Le membre a bien été ajouté à la conversation.'))


Test patch:
Repository: zestedesavoir/zds-site

Issue:
Url des messages privés incorrecte
Depuis le refracto de @GerardPaligot, les urls des mps sont devenues `http://127.0.0.1:8000/mp/39/<bound%20method PrivateTopic.slug of <PrivateTopic%3A Cocuu>>/messages/` !



Discussion:
Je ne parviens pas à reproduire le bug. Est-ce que tu pourrais m'indiquer la manipulation à suivre ?

Edit : C'est bon, j'ai trouvé.


Resolving patch:
diff --git a/zds/mp/models.py b/zds/mp/models.py
--- a/zds/mp/models.py
+++ b/zds/mp/models.py
@@ -45,7 +45,7 @@ def get_absolute_url(self):
         :return: PrivateTopic object URL
         :rtype: str
         """
-        return reverse('private-posts-list', args=[self.pk, self.slug])
+        return reverse('private-posts-list', args=[self.pk, self.slug()])
 
     def slug(self):
         """
diff --git a/zds/mp/views.py b/zds/mp/views.py
--- a/zds/mp/views.py
+++ b/zds/mp/views.py
@@ -437,7 +437,7 @@ def get(self, request, *args, **kwargs):
         self.current_post = self.get_object()
         form = self.form_class(self.topic, initial={'text': self.current_post.text})
         form.helper.form_action = reverse('private-posts-edit',
-                                          args=[self.topic.pk, self.topic.slug, self.current_post.pk])
+                                          args=[self.topic.pk, self.topic.slug(), self.current_post.pk])
         return render(request, self.template_name, {
             'post': self.current_post,
             'topic': self.topic,


Test patch:
diff --git a/zds/mp/tests/tests_models.py b/zds/mp/tests/tests_models.py
--- a/zds/mp/tests/tests_models.py
+++ b/zds/mp/tests/tests_models.py
@@ -37,7 +37,7 @@ def test_unicode(self):
         self.assertEqual(self.topic1.__unicode__(), self.topic1.title)
 
     def test_absolute_url(self):
-        url = reverse('private-posts-list', args=[self.topic1.pk, self.topic1.slug])
+        url = reverse('private-posts-list', args=[self.topic1.pk, self.topic1.slug()])
 
         self.assertEqual(self.topic1.get_absolute_url(), url)
Repository: zestedesavoir/zds-site

Issue:
Relase 1.7 : le slug dans un mp incorect
Version : Beta 1.7-RC2

Scénario : 
- J'ai crée un MP avec 1 participant "test"
- J'ai cliqué sur "Ajouter un membre" et j'ai rajouté "test2"
- L'url de mon MP est devenu : `http://beta.zestedesavoir.com/mp/3101/%3Cbound%20method%20PrivateTopic.slug%20of%20%3CPrivateTopic%3A%20test%3E%3E/messages/`

Il y'a donc un petit problème par là.



Discussion:
Je suppose que ca vient d'ici ? https://github.com/zestedesavoir/zds-site/pull/2424

( @SpaceFox on marque en milestone 1.7 pour s'y retrouver ?)

@Eskimon : Ce que tu link, c'est ma PR incomplète pour corriger l'erreur (qui avait déjà été remonté pour d'autres cas).

La correction du bug est extrêmement simple : changer `self.object.slug` en `self.object.slug()` [ici](https://github.com/zestedesavoir/zds-site/blob/01cc3534f09f19c94d0f6f0c1caebe70f47a4fbb/zds/mp/views.py#L205).

Ok super :) je tag facile du coup :)

Par contre c'est bloquant si on ne peut plus utiliser les MP.

Non, non, on peut utiliser les MPs. Les slugs ne sont pas utilisés dans le back, c'est juste pour faire des URLs jolies ...


Resolving patch:
diff --git a/zds/mp/forms.py b/zds/mp/forms.py
--- a/zds/mp/forms.py
+++ b/zds/mp/forms.py
@@ -88,7 +88,7 @@ class PrivatePostForm(forms.Form):
     def __init__(self, topic, *args, **kwargs):
         super(PrivatePostForm, self).__init__(*args, **kwargs)
         self.helper = FormHelper()
-        self.helper.form_action = reverse('private-posts-new', args=[topic.pk, topic.slug])
+        self.helper.form_action = reverse('private-posts-new', args=[topic.pk, topic.slug()])
         self.helper.form_method = 'post'
 
         self.helper.layout = Layout(
diff --git a/zds/mp/views.py b/zds/mp/views.py
--- a/zds/mp/views.py
+++ b/zds/mp/views.py
@@ -202,7 +202,7 @@ def post(self, request, *args, **kwargs):
         except ObjectDoesNotExist:
             messages.warning(request, _(u'Le membre que vous avez essayé d\'ajouter ne peut pas être contacté.'))
 
-        return redirect(reverse('private-posts-list', args=[self.object.pk, self.object.slug]))
+        return redirect(reverse('private-posts-list', args=[self.object.pk, self.object.slug()]))
 
 
 class PrivateTopicLeaveList(MultipleObjectMixin, RedirectView):


Test patch: