mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-10-31 15:50:03 +01:00 
			
		
		
		
	Dynamic user research
This commit is contained in:
		| @@ -1,33 +0,0 @@ | |||||||
| # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay |  | ||||||
| # SPDX-License-Identifier: GPL-3.0-or-later |  | ||||||
|  |  | ||||||
| from crispy_forms.helper import FormHelper |  | ||||||
| from crispy_forms.layout import Layout, Submit |  | ||||||
| from django.contrib.auth.models import User |  | ||||||
| from django.db.models import CharField |  | ||||||
| from django_filters import FilterSet, CharFilter |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class UserFilter(FilterSet): |  | ||||||
|     class Meta: |  | ||||||
|         model = User |  | ||||||
|         fields = ['last_name', 'first_name', 'username', 'profile__section'] |  | ||||||
|         filter_overrides = { |  | ||||||
|             CharField: { |  | ||||||
|                 'filter_class': CharFilter, |  | ||||||
|                 'extra': lambda f: { |  | ||||||
|                     'lookup_expr': 'icontains' |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class UserFilterFormHelper(FormHelper): |  | ||||||
|     form_method = 'GET' |  | ||||||
|     layout = Layout( |  | ||||||
|         'last_name', |  | ||||||
|         'first_name', |  | ||||||
|         'username', |  | ||||||
|         'profile__section', |  | ||||||
|         Submit('Submit', 'Apply Filter'), |  | ||||||
|     ) |  | ||||||
| @@ -31,7 +31,11 @@ class ClubTable(tables.Table): | |||||||
|  |  | ||||||
| class UserTable(tables.Table): | class UserTable(tables.Table): | ||||||
|     section = tables.Column(accessor='profile.section') |     section = tables.Column(accessor='profile.section') | ||||||
|     solde = tables.Column(accessor='note.balance') |  | ||||||
|  |     balance = tables.Column(accessor='note.balance', verbose_name=_("Balance")) | ||||||
|  |  | ||||||
|  |     def render_balance(self, value): | ||||||
|  |         return pretty_money(value) | ||||||
|  |  | ||||||
|     class Meta: |     class Meta: | ||||||
|         attrs = { |         attrs = { | ||||||
| @@ -40,6 +44,10 @@ class UserTable(tables.Table): | |||||||
|         template_name = 'django_tables2/bootstrap4.html' |         template_name = 'django_tables2/bootstrap4.html' | ||||||
|         fields = ('last_name', 'first_name', 'username', 'email') |         fields = ('last_name', 'first_name', 'username', 'email') | ||||||
|         model = User |         model = User | ||||||
|  |         row_attrs = { | ||||||
|  |             'class': 'table-row', | ||||||
|  |             'data-href': lambda record: record.pk | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
| class MembershipTable(tables.Table): | class MembershipTable(tables.Table): | ||||||
|   | |||||||
| @@ -27,7 +27,6 @@ from note.tables import HistoryTable, AliasTable | |||||||
| from permission.backends import PermissionBackend | from permission.backends import PermissionBackend | ||||||
| from permission.views import ProtectQuerysetMixin | from permission.views import ProtectQuerysetMixin | ||||||
|  |  | ||||||
| from .filters import UserFilter, UserFilterFormHelper |  | ||||||
| from .forms import SignUpForm, ProfileForm, ClubForm, MembershipForm, CustomAuthenticationForm | from .forms import SignUpForm, ProfileForm, ClubForm, MembershipForm, CustomAuthenticationForm | ||||||
| from .models import Club, Membership | from .models import Club, Membership | ||||||
| from .tables import ClubTable, UserTable, MembershipTable | from .tables import ClubTable, UserTable, MembershipTable | ||||||
| @@ -152,18 +151,29 @@ class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): | |||||||
|     model = User |     model = User | ||||||
|     table_class = UserTable |     table_class = UserTable | ||||||
|     template_name = 'member/user_list.html' |     template_name = 'member/user_list.html' | ||||||
|     filter_class = UserFilter |  | ||||||
|     formhelper_class = UserFilterFormHelper |  | ||||||
|  |  | ||||||
|     def get_queryset(self, **kwargs): |     def get_queryset(self, **kwargs): | ||||||
|         qs = super().get_queryset() |         qs = super().get_queryset() | ||||||
|         self.filter = self.filter_class(self.request.GET, queryset=qs) |         if "search" in self.request.GET: | ||||||
|         self.filter.form.helper = self.formhelper_class() |             pattern = self.request.GET["search"] | ||||||
|         return self.filter.qs |  | ||||||
|  |             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(note__alias__name__iregex="^" + pattern) | ||||||
|  |                 | Q(note__alias__normalized_name__iregex=Alias.normalize("^" + pattern)) | ||||||
|  |             ) | ||||||
|  |         else: | ||||||
|  |             qs = qs.none() | ||||||
|  |  | ||||||
|  |         return qs | ||||||
|  |  | ||||||
|     def get_context_data(self, **kwargs): |     def get_context_data(self, **kwargs): | ||||||
|         context = super().get_context_data(**kwargs) |         context = super().get_context_data(**kwargs) | ||||||
|         context["filter"] = self.filter |  | ||||||
|         return context |         return context | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -949,7 +949,7 @@ msgid "search clubs" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: templates/member/club_list.html:12 | #: templates/member/club_list.html:12 | ||||||
| msgid "Créer un club" | msgid "Create club" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: templates/member/club_list.html:19 | #: templates/member/club_list.html:19 | ||||||
|   | |||||||
| @@ -952,8 +952,8 @@ msgid "search clubs" | |||||||
| msgstr "Chercher un club" | msgstr "Chercher un club" | ||||||
|  |  | ||||||
| #: templates/member/club_list.html:12 | #: templates/member/club_list.html:12 | ||||||
| msgid "Créer un club" | msgid "Create club" | ||||||
| msgstr "" | msgstr "Créer un club" | ||||||
|  |  | ||||||
| #: templates/member/club_list.html:19 | #: templates/member/club_list.html:19 | ||||||
| msgid "club listing " | msgid "club listing " | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
|         </h4> |         </h4> | ||||||
|         <input class="form-control mx-auto w-25" type="text" onkeyup="search_field_moved();return(false);" id="search_field"/> |         <input class="form-control mx-auto w-25" type="text" onkeyup="search_field_moved();return(false);" id="search_field"/> | ||||||
|         <hr> |         <hr> | ||||||
|         <a class="btn btn-primary text-center my-4" href="{% url 'member:club_create' %}">{% trans "Créer un club" %}</a> |         <a class="btn btn-primary text-center my-4" href="{% url 'member:club_create' %}">{% trans "Create club" %}</a> | ||||||
|     </div> |     </div> | ||||||
| </div> | </div> | ||||||
| <div class="row justify-content-center">    | <div class="row justify-content-center">    | ||||||
|   | |||||||
| @@ -2,28 +2,44 @@ | |||||||
| {% load render_table from django_tables2 %} | {% load render_table from django_tables2 %} | ||||||
| {% load crispy_forms_tags%} | {% load crispy_forms_tags%} | ||||||
| {% block content %} | {% block content %} | ||||||
|  |     <input id="searchbar" type="text" class="form-control" placeholder="Nom/prénom/note/section ..."> | ||||||
|  |  | ||||||
| <a class="btn btn-primary" href="{% url 'member:signup' %}">New User</a> |     <hr> | ||||||
|  |  | ||||||
| <div class="row"> |     <div id="user_table"> | ||||||
| {% crispy filter.form filter.form.helper %} |         {% render_table table %} | ||||||
| </div> |  | ||||||
| <div class="row"> |  | ||||||
|     <div id="replaceable-content" class="col-6"> |  | ||||||
|         {% render_table  table %} |  | ||||||
|     </div> |     </div> | ||||||
| </div> |  | ||||||
|  |  | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
| {% block extrajavascript %} | {% block extrajavascript %} | ||||||
| <script type="text/javascript"> | <script type="text/javascript"> | ||||||
|  |     $(document).ready(function() { | ||||||
|  |         let old_pattern = null; | ||||||
|  |         let searchbar_obj = $("#searchbar"); | ||||||
|  |  | ||||||
| $(document).ready(function($) { |         function reloadTable() { | ||||||
|     $(".table-row").click(function() { |             let pattern = searchbar_obj.val(); | ||||||
|         window.document.location = $(this).data("href"); |  | ||||||
|  |             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> | </script> | ||||||
| {% endblock %} | {% endblock %} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user