diff --git a/apps/member/models.py b/apps/member/models.py
index 80681824ff04c4fcdbba89db06da3b93a1003265..c51a95c8e1581f066365fb9cca34f8cf9d208554 100644
--- a/apps/member/models.py
+++ b/apps/member/models.py
@@ -250,12 +250,18 @@ class Membership(models.Model):
     )
 
     def valid(self):
+        """
+        A membership is valid if today is between the start and the end date.
+        """
         if self.date_end is not None:
             return self.date_start.toordinal() <= datetime.datetime.now().toordinal() < self.date_end.toordinal()
         else:
             return self.date_start.toordinal() <= datetime.datetime.now().toordinal()
 
     def save(self, *args, **kwargs):
+        """
+        Calculate fee and end date before saving the membership and creating the transaction if needed.
+        """
         if self.club.parent_club is not None:
             if not Membership.objects.filter(user=self.user, club=self.club.parent_club).exists():
                 raise ValidationError(_('User is not a member of the parent club') + ' ' + self.club.parent_club.name)
@@ -287,6 +293,9 @@ class Membership(models.Model):
         self.make_transaction()
 
     def make_transaction(self):
+        """
+        Create Membership transaction associated to this membership.
+        """
         if not self.fee or MembershipTransaction.objects.filter(membership=self).exists():
             return
 
diff --git a/apps/member/tables.py b/apps/member/tables.py
index c8a510ff8d5a85c6e7a7195b85c8426d5436a64c..515d78368a55ee98290b8dd8cad87f318d9e5f6c 100644
--- a/apps/member/tables.py
+++ b/apps/member/tables.py
@@ -15,6 +15,9 @@ from .models import Club, Membership
 
 
 class ClubTable(tables.Table):
+    """
+    List all clubs.
+    """
     class Meta:
         attrs = {
             'class': 'table table-condensed table-striped table-hover'
@@ -30,6 +33,9 @@ class ClubTable(tables.Table):
 
 
 class UserTable(tables.Table):
+    """
+    List all users.
+    """
     section = tables.Column(accessor='profile.section')
 
     balance = tables.Column(accessor='note.balance', verbose_name=_("Balance"))
@@ -51,6 +57,9 @@ class UserTable(tables.Table):
 
 
 class MembershipTable(tables.Table):
+    """
+    List all memberships.
+    """
     roles = tables.Column(
         attrs={
             "td": {
@@ -59,7 +68,17 @@ class MembershipTable(tables.Table):
         }
     )
 
+    def render_user(self, value):
+        # If the user has the right, link the displayed user with the page of its detail.
+        s = value.username
+        if PermissionBackend.check_perm(get_current_authenticated_user(), "auth.view_user", value):
+            s = format_html("<a href={url}>{name}</a>",
+                            url=reverse_lazy('member:user_detail', kwargs={"pk": value.pk}), name=s)
+
+        return s
+
     def render_club(self, value):
+        # If the user has the right, link the displayed club with the page of its detail.
         s = value.name
         if PermissionBackend.check_perm(get_current_authenticated_user(), "member.view_club", value):
             s = format_html("<a href={url}>{name}</a>",
@@ -94,6 +113,7 @@ class MembershipTable(tables.Table):
         return t
 
     def render_roles(self, record):
+        # If the user has the right to manage the roles, display the link to manage them
         roles = record.roles.all()
         s = ", ".join(str(role) for role in roles)
         if PermissionBackend.check_perm(get_current_authenticated_user(), "member.change_membership_roles", record):
diff --git a/apps/member/views.py b/apps/member/views.py
index 50c3b8132c13c418e151af833adee93777185bc9..b8048d6efb89cfa5a28441d274cd41de880f45ac 100644
--- a/apps/member/views.py
+++ b/apps/member/views.py
@@ -30,6 +30,9 @@ from .tables import ClubTable, UserTable, MembershipTable
 
 
 class CustomLoginView(LoginView):
+    """
+    Login view, where the user can select its permission mask.
+    """
     form_class = CustomAuthenticationForm
 
     def form_valid(self, form):
@@ -38,6 +41,9 @@ class CustomLoginView(LoginView):
 
 
 class UserUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
+    """
+    Update the user information.
+    """
     model = User
     fields = ['first_name', 'last_name', 'username', 'email']
     template_name = 'member/profile_update.html'
@@ -93,6 +99,7 @@ class UserUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
             user.save()
 
             if olduser.email != user.email:
+                # If the user changed her/his email, then it is unvalidated and a confirmation link is sent.
                 user.profile.email_confirmed = False
                 user.profile.send_email_validation_link()
 
@@ -132,13 +139,16 @@ class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
 
 class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
     """
-    Affiche la liste des utilisateurs, avec une fonction de recherche statique
+    Display user list, with a search bar
     """
     model = User
     table_class = UserTable
     template_name = 'member/user_list.html'
 
     def get_queryset(self, **kwargs):
+        """
+        Filter the user list with the given pattern.
+        """
         qs = super().get_queryset().filter(profile__registration_valid=True)
         if "search" in self.request.GET:
             pattern = self.request.GET["search"]
@@ -150,6 +160,7 @@ class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
                 Q(first_name__iregex=pattern)
                 | Q(last_name__iregex=pattern)
                 | Q(profile__section__iregex=pattern)
+                | Q(profile__username__iregex="^" + pattern)
                 | Q(note__alias__name__iregex="^" + pattern)
                 | Q(note__alias__normalized_name__iregex=Alias.normalize("^" + pattern))
             )
@@ -167,6 +178,9 @@ class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
 
 
 class ProfileAliasView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
+    """
+    View and manage user aliases.
+    """
     model = User
     template_name = 'member/profile_alias.html'
     context_object_name = 'user_object'
@@ -179,6 +193,9 @@ class ProfileAliasView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
 
 
 class PictureUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, DetailView):
+    """
+    Update profile picture of the user note.
+    """
     form_class = ImageForm
 
     def get_context_data(self, **kwargs):
@@ -278,6 +295,9 @@ class ClubListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
 
 
 class ClubDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
+    """
+    Display details of a club
+    """
     model = Club
     context_object_name = "club"
 
@@ -298,6 +318,7 @@ class ClubDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
 
         context['member_list'] = MembershipTable(data=club_member)
 
+        # Check if the user has the right to create a membership, to display the button.
         empty_membership = Membership(
             club=club,
             user=User.objects.first(),
@@ -312,6 +333,9 @@ class ClubDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
 
 
 class ClubAliasView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
+    """
+    Manage aliases of a club.
+    """
     model = Club
     template_name = 'member/club_alias.html'
     context_object_name = 'club'
@@ -324,6 +348,9 @@ class ClubAliasView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
 
 
 class ClubUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
+    """
+    Update the information of a club.
+    """
     model = Club
     context_object_name = "club"
     form_class = ClubForm
@@ -334,6 +361,9 @@ class ClubUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
 
 
 class ClubPictureUpdateView(PictureUpdateView):
+    """
+    Update the profile picture of a club.
+    """
     model = Club
     template_name = 'member/club_picture_update.html'
     context_object_name = 'club'
@@ -343,6 +373,9 @@ class ClubPictureUpdateView(PictureUpdateView):
 
 
 class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
+    """
+    Add a membership to a club.
+    """
     model = Membership
     form_class = MembershipForm
     template_name = 'member/add_members.html'
@@ -352,10 +385,12 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
         form = context['form']
 
         if "club_pk" in self.kwargs:
+            # We create a new membership.
             club = Club.objects.filter(PermissionBackend.filter_queryset(self.request.user, Club, "view"))\
                 .get(pk=self.kwargs["club_pk"])
             form.fields['credit_amount'].initial = club.membership_fee_paid
 
+            # If the concerned club is the BDE, then we add the option that Société générale pays the membership.
             if club.name != "BDE":
                 del form.fields['soge']
             else:
@@ -366,6 +401,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
                 fee += kfet.membership_fee_paid
                 context["total_fee"] = "{:.02f}".format(fee / 100, )
         else:
+            # This is a renewal. Fields can be pre-completed.
             old_membership = self.get_queryset().get(pk=self.kwargs["pk"])
             club = old_membership.club
             user = old_membership.user
@@ -378,6 +414,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
             form.fields['last_name'].initial = user.last_name
             form.fields['first_name'].initial = user.first_name
 
+            # If this is a renewal of a BDE membership, Société générale can pays, if it is not yet done
             if club.name != "BDE" or user.profile.soge:
                 del form.fields['soge']
             else:
@@ -393,6 +430,10 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
         return context
 
     def form_valid(self, form):
+        """
+        Create membership, check that all is good, make transactions
+        """
+        # Get the club that is concerned by the membership
         if "club_pk" in self.kwargs:
             club = Club.objects.filter(PermissionBackend.filter_queryset(self.request.user, Club, "view")) \
                 .get(pk=self.kwargs["club_pk"])
@@ -404,6 +445,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
 
         form.instance.club = club
 
+        # Get form data
         credit_type = form.cleaned_data["credit_type"]
         credit_amount = form.cleaned_data["credit_amount"]
         last_name = form.cleaned_data["last_name"]
@@ -411,6 +453,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
         bank = form.cleaned_data["bank"]
         soge = form.cleaned_data["soge"] and not user.profile.soge and club.name == "BDE"
 
+        # If Société générale pays, then we auto-fill some data
         if soge:
             credit_type = NoteSpecial.objects.get(special_type="Virement bancaire")
             bde = club
@@ -466,6 +509,9 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
                            .format(form.instance.club.membership_start))
             return super().form_invalid(form)
 
+        # Now, all is fine, the membership can be created.
+
+        # Credit note before the membership is created.
         if credit_amount > 0:
             if not last_name or not first_name or (not bank and credit_type.special_type == "Chèque"):
                 if not last_name:
@@ -488,6 +534,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
                 valid=True,
             )
 
+        # If Société générale pays, then we store the information: the bank can't pay twice to a same person.
         if soge:
             user.profile.soge = True
             user.profile.save()
@@ -495,6 +542,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
             kfet = Club.objects.get(name="Kfet")
             kfet_fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
 
+            # Get current membership, to get the end date
             old_membership = Membership.objects.filter(
                 club__name="Kfet",
                 user=user,
@@ -522,6 +570,9 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
 
 
 class ClubManageRolesView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
+    """
+    Manage the roles of a user in a club
+    """
     model = Membership
     form_class = MembershipForm
     template_name = 'member/add_members.html'
@@ -534,6 +585,7 @@ class ClubManageRolesView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
 
     def get_form(self, form_class=None):
         form = super().get_form(form_class)
+        # We don't create a full membership, we only update one field
         form.fields['user'].disabled = True
         del form.fields['date_start']
         del form.fields['credit_type']
diff --git a/apps/note/views.py b/apps/note/views.py
index 4f2321fb28c5a511b89de532d1f75b4313dc3463..88d47847288fe6b79c07ea8c01ad90d106b45343 100644
--- a/apps/note/views.py
+++ b/apps/note/views.py
@@ -45,6 +45,7 @@ class TransactionCreateView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTabl
             .filter(PermissionBackend.filter_queryset(self.request.user, NoteSpecial, "view"))\
             .order_by("special_type").all()
 
+        # Add a shortcut for entry page for open activities
         if "activity" in settings.INSTALLED_APPS:
             from activity.models import Activity
             context["activities_open"] = Activity.objects.filter(open=True).filter(
@@ -56,7 +57,7 @@ class TransactionCreateView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTabl
 
 class TransactionTemplateCreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
     """
-    Create TransactionTemplate
+    Create Transaction template
     """
     model = TransactionTemplate
     form_class = TransactionTemplateForm
@@ -65,7 +66,7 @@ class TransactionTemplateCreateView(ProtectQuerysetMixin, LoginRequiredMixin, Cr
 
 class TransactionTemplateListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
     """
-    List TransactionsTemplates
+    List Transaction templates
     """
     model = TransactionTemplate
     table_class = ButtonTable
@@ -73,6 +74,7 @@ class TransactionTemplateListView(ProtectQuerysetMixin, LoginRequiredMixin, Sing
 
 class TransactionTemplateUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
     """
+    Update Transaction template
     """
     model = TransactionTemplate
     form_class = TransactionTemplateForm
diff --git a/apps/registration/api/__init__.py b/apps/registration/api/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/apps/registration/forms.py b/apps/registration/forms.py
index 3ca14ca1a0a6500bc2a508af87ae7d5d8933265e..4955c4a8f685b23b05c952af1c97befa1e25ae09 100644
--- a/apps/registration/forms.py
+++ b/apps/registration/forms.py
@@ -10,6 +10,9 @@ from note_kfet.inputs import AmountInput
 
 
 class SignUpForm(UserCreationForm):
+    """
+    Pre-register users with all information
+    """
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.fields['username'].widget.attrs.pop("autofocus", None)
@@ -25,6 +28,9 @@ class SignUpForm(UserCreationForm):
 
 
 class ValidationForm(forms.Form):
+    """
+    Validate the inscription of the new users and pay memberships.
+    """
     soge = forms.BooleanField(
         label=_("Inscription paid by Société Générale"),
         required=False,
@@ -66,6 +72,7 @@ class ValidationForm(forms.Form):
         initial=True,
     )
 
+    # The user can join the Kfet club at the inscription
     join_Kfet = forms.BooleanField(
         label=_("Join Kfet Club"),
         required=False,
diff --git a/apps/registration/tables.py b/apps/registration/tables.py
index 7fd7537f178aa74dfa01b150f97b28dbdf87ed1a..7068f6ca0646d60cbaa9df09e7271913fc8e0ea8 100644
--- a/apps/registration/tables.py
+++ b/apps/registration/tables.py
@@ -6,6 +6,9 @@ from django.contrib.auth.models import User
 
 
 class FutureUserTable(tables.Table):
+    """
+    Display the list of pre-registered users
+    """
     phone_number = tables.Column(accessor='profile.phone_number')
 
     section = tables.Column(accessor='profile.section')
diff --git a/apps/registration/views.py b/apps/registration/views.py
index b3d4766ce6af50dfe031bf7dca9019b7c6f21f92..2daca03786fcf6c0648f450837a0e56aebacf1c3 100644
--- a/apps/registration/views.py
+++ b/apps/registration/views.py
@@ -5,13 +5,12 @@ from django.conf import settings
 from django.contrib.auth.mixins import LoginRequiredMixin
 from django.contrib.auth.models import User
 from django.core.exceptions import ValidationError
+from django.db.models import Q
 from django.shortcuts import resolve_url, redirect
 from django.urls import reverse_lazy
-from django.utils.decorators import method_decorator
 from django.utils.http import urlsafe_base64_decode
 from django.utils.translation import gettext_lazy as _
 from django.views import View
-from django.views.decorators.csrf import csrf_protect
 from django.views.generic import CreateView, TemplateView, DetailView, FormView
 from django_tables2 import SingleTableView
 from member.forms import ProfileForm
@@ -46,11 +45,13 @@ class UserCreateView(CreateView):
         """
         If the form is valid, then the user is created with is_active set to False
         so that the user cannot log in until the email has been validated.
+        The user must also wait that someone validate her/his account.
         """
         profile_form = ProfileForm(data=self.request.POST)
         if not profile_form.is_valid():
             return self.form_invalid(form)
 
+        # Save the user and the profile
         user = form.save(commit=False)
         user.is_active = False
         profile_form.instance.user = user
@@ -67,16 +68,15 @@ class UserCreateView(CreateView):
 
 
 class UserValidateView(TemplateView):
+    """
+    A view to validate the email address.
+    """
     title = _("Email validation")
     template_name = 'registration/email_validation_complete.html'
 
-    @method_decorator(csrf_protect)
-    def dispatch(self, *args, **kwargs):
+    def get(self, *args, **kwargs):
         """
-        The dispatch method looks at the request to determine whether it is a GET, POST, etc,
-        and relays the request to a matching method if one is defined, or raises HttpResponseNotAllowed
-        if not. We chose to check the token in the dispatch method to mimic PasswordReset from
-        django.contrib.auth
+        With a given token and user id (in params), validate the email address.
         """
         assert 'uidb64' in kwargs and 'token' in kwargs
 
@@ -84,18 +84,23 @@ class UserValidateView(TemplateView):
         user = self.get_user(kwargs['uidb64'])
         token = kwargs['token']
 
+        # Validate the token
         if user is not None and email_validation_token.check_token(user, token):
             self.validlink = True
+            # The user must wait that someone validates the account before the user can be active and login.
             user.is_active = user.profile.registration_valid
             user.profile.email_confirmed = True
             user.save()
             user.profile.save()
             return super().dispatch(*args, **kwargs)
         else:
-            # Display the "Account Activation unsuccessful" page.
+            # Display the "Email validation unsuccessful" page.
             return self.render_to_response(self.get_context_data())
 
     def get_user(self, uidb64):
+        """
+        Get user from the base64-encoded string.
+        """
         try:
             # urlsafe_base64_decode() decodes to bytestring
             uid = urlsafe_base64_decode(uidb64).decode()
@@ -118,16 +123,19 @@ class UserValidateView(TemplateView):
 
 
 class UserValidationEmailSentView(TemplateView):
+    """
+    Display the information that the validation link has been sent.
+    """
     template_name = 'registration/email_validation_email_sent.html'
     title = _('Email validation email sent')
 
 
 class UserResendValidationEmailView(LoginRequiredMixin, ProtectQuerysetMixin, DetailView):
+    """
+    Rensend the email validation link.
+    """
     model = User
 
-    def get_queryset(self, **kwargs):
-        return super().get_queryset(**kwargs).filter(profile__email_confirmed=False)
-
     def get(self, request, *args, **kwargs):
         user = self.get_object()
 
@@ -139,14 +147,35 @@ class UserResendValidationEmailView(LoginRequiredMixin, ProtectQuerysetMixin, De
 
 class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
     """
-    Affiche la liste des utilisateurs, avec une fonction de recherche statique
+    Display pre-registered users, with a search bar
     """
     model = User
     table_class = FutureUserTable
     template_name = 'registration/future_user_list.html'
 
     def get_queryset(self, **kwargs):
-        return super().get_queryset().filter(profile__registration_valid=False)
+        """
+        Filter the table with the given parameter.
+        :param kwargs:
+        :return:
+        """
+        qs = super().get_queryset().filter(profile__registration_valid=False)
+        if "search" in self.request.GET:
+            pattern = self.request.GET["search"]
+
+            if not pattern:
+                return qs.none()
+
+            qs = qs.filter(
+                Q(first_name__iregex=pattern)
+                | Q(last_name__iregex=pattern)
+                | Q(profile__section__iregex=pattern)
+                | Q(username__iregex="^" + pattern)
+            )
+        else:
+            qs = qs.none()
+
+        return qs[:20]
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
@@ -158,7 +187,7 @@ class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableVi
 
 class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView, FormView):
     """
-    Affiche les informations sur un utilisateur, sa note, ses clubs...
+    Display information about a pre-registered user, in order to complete the registration.
     """
     model = User
     form_class = ValidationForm
@@ -194,6 +223,7 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView,
     def form_valid(self, form):
         user = self.object = self.get_object()
 
+        # Get form data
         soge = form.cleaned_data["soge"]
         credit_type = form.cleaned_data["credit_type"]
         credit_amount = form.cleaned_data["credit_amount"]
@@ -204,6 +234,7 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView,
         join_Kfet = form.cleaned_data["join_Kfet"]
 
         if soge:
+            # If Société Générale pays the inscription, the user joins the two clubs
             join_BDE = True
             join_Kfet = True
 
@@ -218,6 +249,7 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView,
             fee += kfet_fee
 
         if soge:
+            # Fill payment information if Société Générale pays the inscription
             credit_type = NoteSpecial.objects.get(special_type="Virement bancaire")
             credit_amount = fee
             bank = "Société générale"
@@ -226,6 +258,7 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView,
             form.add_error('join_Kfet', _("You must join BDE club before joining Kfet club."))
 
         if fee > credit_amount:
+            # Check if the user credits enough money
             form.add_error('credit_type',
                            _("The entered amount is not enough for the memberships, should be at least {}")
                            .format(pretty_money(fee)))
@@ -241,14 +274,18 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView,
                     form.add_error('bank', _("This field is required."))
                 return self.form_invalid(form)
 
+        # Save the user and finally validate the registration
+        # Saving the user creates the associated note
         ret = super().form_valid(form)
         user.is_active = user.profile.email_confirmed
         user.profile.registration_valid = True
+        # Store if Société générale paid for next years
         user.profile.soge = soge
         user.save()
         user.profile.save()
 
         if credit_type is not None and credit_amount > 0:
+            # Credit the note
             SpecialTransaction.objects.create(
                 source=credit_type,
                 destination=user.note,
@@ -262,6 +299,7 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView,
             )
 
         if join_BDE:
+            # Create membership for the user to the BDE starting today
             membership = Membership.objects.create(
                 club=bde,
                 user=user,
@@ -271,6 +309,7 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView,
             membership.save()
 
         if join_Kfet:
+            # Create membership for the user to the Kfet starting today
             membership = Membership.objects.create(
                 club=kfet,
                 user=user,
@@ -287,10 +326,13 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView,
 
 class FutureUserInvalidateView(ProtectQuerysetMixin, LoginRequiredMixin, View):
     """
-    Affiche les informations sur un utilisateur, sa note, ses clubs...
+    Delete a pre-registered user.
     """
 
-    def dispatch(self, request, *args, **kwargs):
+    def get(self, request, *args, **kwargs):
+        """
+        Delete the pre-registered user which id is given in the URL.
+        """
         user = User.objects.filter(profile__registration_valid=False)\
             .filter(PermissionBackend.filter_queryset(request.user, User, "change", "is_valid"))\
             .get(pk=self.kwargs["pk"])
diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po
index 5fe4ad5abbdde60364dd085b5af04ebc98cd0505..1e79122016ff40b3bc015df0403087ae6d551418 100644
--- a/locale/de/LC_MESSAGES/django.po
+++ b/locale/de/LC_MESSAGES/django.po
@@ -1267,7 +1267,7 @@ msgid "New user"
 msgstr ""
 
 #: templates/registration/future_user_list.html:17
-msgid "There is no pending user."
+msgid "There is no pending user with this pattern."
 msgstr ""
 
 #: templates/registration/logged_out.html:8
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index c666c12a5baaa4646dd7a797028ea747a1d2b67b..4e282beaa9bed96f0d967653afe2d94c4012c113 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -1274,8 +1274,8 @@ msgid "New user"
 msgstr "Nouvel utilisateur"
 
 #: templates/registration/future_user_list.html:17
-msgid "There is no pending user."
-msgstr "Il n'y a pas d'inscription en attente."
+msgid "There is no pending user with this pattern."
+msgstr "Il n'y a pas d'inscription en attente avec cette entrée."
 
 #: templates/registration/logged_out.html:8
 msgid "Thanks for spending some quality time with the Web site today."
diff --git a/static/js/transfer.js b/static/js/transfer.js
index 9aff4649cba3cf8972b9266d4d4634e1fe98cd12..e5aafc3903864e3ecf256cb6ed4c0f601c2ad581 100644
--- a/static/js/transfer.js
+++ b/static/js/transfer.js
@@ -28,7 +28,6 @@ function reset() {
 }
 
 $(document).ready(function() {
-    console.log(42);
     autoCompleteNote("source_note", "source_alias_matched", "source_note_list", sources, sources_notes_display,
         "source_alias", "source_note", "user_note", "profile_pic");
     autoCompleteNote("dest_note", "dest_alias_matched", "dest_note_list", dests, dests_notes_display,
@@ -72,7 +71,6 @@ $(document).ready(function() {
     $("label[for='type_credit']").attr('class', 'btn btn-sm btn-outline-primary');
     $("label[for='type_debit']").attr('class', 'btn btn-sm btn-outline-primary');
 
-    console.log("#type_" + location.hash.substr(1));
     if (location.hash)
         $("#type_" + location.hash.substr(1)).click();
     else
diff --git a/templates/activity/activity_detail.html b/templates/activity/activity_detail.html
index 841820650e3ee5b1fce310fb83dbdf5abb8b4e83..7ee9f7c0f82322613072cb45d300c5bf1c042b5e 100644
--- a/templates/activity/activity_detail.html
+++ b/templates/activity/activity_detail.html
@@ -118,7 +118,6 @@
     });
 
     $("#validate_activity").click(function () {
-        console.log(42);
         $.ajax({
             url: "/api/activity/activity/{{ activity.pk }}/",
             type: "PATCH",
diff --git a/templates/member/club_list.html b/templates/member/club_list.html
index 2653ace8388704aa45e3ba8cd235de9ab4e4ab63..4682164cfb44384bf192bb05df60a2dff6bf7e0c 100644
--- a/templates/member/club_list.html
+++ b/templates/member/club_list.html
@@ -36,7 +36,6 @@ function getInfo() {
     if (asked.length >= 1) {
         $.getJSON("/api/members/club/?format=json&search="+asked, function(buttons){
             let selected_id = buttons.results.map((a => "#row-"+a.id));
-            console.log(selected_id.join());
             $(".table-row,"+selected_id.join()).show();
             $(".table-row").not(selected_id.join()).hide();
             
diff --git a/templates/member/user_list.html b/templates/member/user_list.html
index d0eaaedb288c85d568eff2a4a7af449404c1fe50..0bcd7e89c2dd9e2db54b72e2fd69ccdb70a0d6a4 100644
--- a/templates/member/user_list.html
+++ b/templates/member/user_list.html
@@ -7,7 +7,13 @@
     <hr>
 
     <div id="user_table">
-        {% render_table table %}
+        {% if table.data %}
+            {% render_table table %}
+        {% else %}
+            <div class="alert alert-warning">
+                {% trans "There is no pending user with this pattern." %}
+            </div>
+        {% endif %}
     </div>
 
 {% endblock %}
diff --git a/templates/note/transactiontemplate_list.html b/templates/note/transactiontemplate_list.html
index af0a02b4ebbbd9d7bf748f7e8d1b04e00421edba..cf9bc5edc91b2fb9ce28dacba346b19b24cbf6ec 100644
--- a/templates/note/transactiontemplate_list.html
+++ b/templates/note/transactiontemplate_list.html
@@ -37,7 +37,6 @@ function getInfo() {
     if (asked.length >= 1) {
         $.getJSON("/api/note/transaction/template/?format=json&search="+asked, function(buttons){
             let selected_id = buttons.results.map((a => "#row-"+a.id));
-            console.log(selected_id.join());
             $(".table-row,"+selected_id.join()).show();
             $(".table-row").not(selected_id.join()).hide();
             
diff --git a/templates/registration/future_user_list.html b/templates/registration/future_user_list.html
index 490fe2abce657b41bf2612d798500020a71e62ac..1e10dcbb099214d7b9a9ac0a7d928c46063953e2 100644
--- a/templates/registration/future_user_list.html
+++ b/templates/registration/future_user_list.html
@@ -5,24 +5,49 @@
 
 {% block content %}
     <a href="{% url 'registration:signup' %}"><button class="btn btn-primary btn-block">{% trans "New user" %}</button></a>
-
+    <hr>
+    <input id="searchbar" type="text" class="form-control" placeholder="Nom/prénom/note/section ...">
     <hr>
 
-    {% if table.data %}
-        <div id="user_table">
+    <div id="user_table">
+        {% if table.data %}
             {% render_table table %}
-        </div>
-    {% else %}
-        <div class="alert alert-warning">
-            {% trans "There is no pending user." %}
-        </div>
-    {% endif %}
+        {% else %}
+            <div class="alert alert-warning">
+                {% trans "There is no pending user with this pattern." %}
+            </div>
+        {% endif %}
+    </div>
 {% endblock %}
 
 {% block extrajavascript %}
 <script type="text/javascript">
-    $(".table-row").click(function() {
-        window.document.location = $(this).data("href");
+    $(document).ready(function() {
+        let old_pattern = null;
+        let searchbar_obj = $("#searchbar");
+
+        function reloadTable() {
+            let pattern = searchbar_obj.val();
+
+            if (pattern === old_pattern || pattern === "")
+                return;
+
+            $("#user_table").load(location.href + "?search=" + pattern.replace(" ", "%20") + " #user_table", init);
+
+            $(".table-row").click(function() {
+                window.document.location = $(this).data("href");
+            });
+        }
+
+        searchbar_obj.keyup(reloadTable);
+
+        function init() {
+            $(".table-row").click(function() {
+                window.document.location = $(this).data("href");
+            });
+        }
+
+        init();
     });
 </script>
 {% endblock %}