mirror of https://gitlab.crans.org/bde/nk20
Order note research results: match first aliases then normalized names
This commit is contained in:
parent
ca7f4791ed
commit
a9258c332a
|
@ -4,14 +4,15 @@
|
|||
from django.conf.urls import url, include
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models import Q
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from rest_framework import routers, serializers
|
||||
from rest_framework.filters import SearchFilter
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
from activity.api.urls import register_activity_urls
|
||||
from api.viewsets import ReadProtectedModelViewSet
|
||||
from member.api.urls import register_members_urls
|
||||
from note.api.urls import register_note_urls
|
||||
from note.models import Alias
|
||||
from treasury.api.urls import register_treasury_urls
|
||||
from logs.api.urls import register_logs_urls
|
||||
from permission.api.urls import register_permission_urls
|
||||
|
@ -52,9 +53,47 @@ class UserViewSet(ReadProtectedModelViewSet):
|
|||
"""
|
||||
queryset = User.objects.all()
|
||||
serializer_class = UserSerializer
|
||||
filter_backends = [DjangoFilterBackend, SearchFilter]
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = ['id', 'username', 'first_name', 'last_name', 'email', 'is_superuser', 'is_staff', 'is_active', ]
|
||||
search_fields = ['$username', '$first_name', '$last_name', '$note__alias__name', '$note__alias__normalized_name', ]
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = super().get_queryset().order_by("username")
|
||||
|
||||
if "search" in self.request.GET:
|
||||
pattern = self.request.GET["search"]
|
||||
|
||||
# We match first a user by its username, then if an alias is matched without normalization
|
||||
# And finally if the normalized pattern matches a normalized alias.
|
||||
queryset = queryset.filter(
|
||||
username__iregex="^" + pattern
|
||||
).union(
|
||||
queryset.filter(
|
||||
Q(note__alias__name__iregex="^" + pattern)
|
||||
& ~Q(username__iregex="^" + pattern)
|
||||
), all=True).union(
|
||||
queryset.filter(
|
||||
Q(note__alias__normalized_name__iregex="^" + Alias.normalize(pattern))
|
||||
& ~Q(note__alias__name__iregex="^" + pattern)
|
||||
& ~Q(username__iregex="^" + pattern)
|
||||
),
|
||||
all=True).union(
|
||||
queryset.filter(
|
||||
Q(note__alias__normalized_name__iregex="^" + pattern.lower())
|
||||
& ~Q(note__alias__normalized_name__iregex="^" + Alias.normalize(pattern))
|
||||
& ~Q(note__alias__name__iregex="^" + pattern)
|
||||
& ~Q(username__iregex="^" + pattern)
|
||||
),
|
||||
all=True).union(
|
||||
queryset.filter(
|
||||
(Q(last_name__iregex="^" + pattern) | Q(first_name__iregex="^" + pattern))
|
||||
& ~Q(note__alias__normalized_name__iregex="^" + pattern.lower())
|
||||
& ~Q(note__alias__normalized_name__iregex="^" + Alias.normalize(pattern))
|
||||
& ~Q(note__alias__name__iregex="^" + pattern)
|
||||
& ~Q(username__iregex="^" + pattern)
|
||||
),
|
||||
all=True)
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
# This ViewSet is the only one that is accessible from all authenticated users!
|
||||
|
|
|
@ -180,9 +180,9 @@ class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
|||
"""
|
||||
Filter the user list with the given pattern.
|
||||
"""
|
||||
qs = super().get_queryset().distinct("pk").annotate(alias=F("note__alias__name"))\
|
||||
qs = super().get_queryset().distinct("username").annotate(alias=F("note__alias__name"))\
|
||||
.annotate(normalized_alias=F("note__alias__normalized_name"))\
|
||||
.filter(profile__registration_valid=True)
|
||||
.filter(profile__registration_valid=True).order_by("username")
|
||||
if "search" in self.request.GET:
|
||||
pattern = self.request.GET["search"]
|
||||
|
||||
|
@ -190,13 +190,16 @@ class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
|||
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)
|
||||
| Q(alias__iregex=pattern)
|
||||
| Q(normalized_alias__iregex=Alias.normalize(pattern))
|
||||
)
|
||||
username__iregex="^" + pattern
|
||||
).union(
|
||||
qs.filter(
|
||||
(Q(alias__iregex="^" + pattern)
|
||||
| Q(normalized_alias__iregex="^" + Alias.normalize(pattern))
|
||||
| Q(last_name__iregex="^" + pattern)
|
||||
| Q(first_name__iregex="^" + pattern)
|
||||
| Q(email__istartswith=pattern))
|
||||
& ~Q(username__iregex="^" + pattern)
|
||||
), all=True)
|
||||
else:
|
||||
qs = qs.none()
|
||||
|
||||
|
|
|
@ -40,9 +40,19 @@ class NotePolymorphicViewSet(ReadOnlyProtectedModelViewSet):
|
|||
|
||||
alias = self.request.query_params.get("alias", ".*")
|
||||
queryset = queryset.filter(
|
||||
Q(alias__name__regex="^" + alias)
|
||||
| Q(alias__normalized_name__regex="^" + Alias.normalize(alias))
|
||||
| Q(alias__normalized_name__regex="^" + alias.lower()))
|
||||
name__iregex="^" + alias
|
||||
).union(
|
||||
queryset.filter(
|
||||
Q(normalized_name__iregex="^" + Alias.normalize(alias))
|
||||
& ~Q(name__iregex="^" + alias)
|
||||
),
|
||||
all=True).union(
|
||||
queryset.filter(
|
||||
Q(normalized_name__iregex="^" + alias.lower())
|
||||
& ~Q(normalized_name__iregex="^" + Alias.normalize(alias))
|
||||
& ~Q(name__iregex="^" + alias)
|
||||
),
|
||||
all=True)
|
||||
|
||||
return queryset.distinct()
|
||||
|
||||
|
@ -85,9 +95,19 @@ class AliasViewSet(ReadProtectedModelViewSet):
|
|||
|
||||
alias = self.request.query_params.get("alias", ".*")
|
||||
queryset = queryset.filter(
|
||||
Q(name__regex="^" + alias)
|
||||
| Q(normalized_name__regex="^" + Alias.normalize(alias))
|
||||
| Q(normalized_name__regex="^" + alias.lower()))
|
||||
name__iregex="^" + alias
|
||||
).union(
|
||||
queryset.filter(
|
||||
Q(normalized_name__iregex="^" + Alias.normalize(alias))
|
||||
& ~Q(name__iregex="^" + alias)
|
||||
),
|
||||
all=True).union(
|
||||
queryset.filter(
|
||||
Q(normalized_name__iregex="^" + alias.lower())
|
||||
& ~Q(normalized_name__iregex="^" + Alias.normalize(alias))
|
||||
& ~Q(name__iregex="^" + alias)
|
||||
),
|
||||
all=True)
|
||||
|
||||
return queryset
|
||||
|
||||
|
@ -108,13 +128,25 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
|
|||
queryset = super().get_queryset()
|
||||
|
||||
alias = self.request.query_params.get("alias", ".*")
|
||||
queryset = queryset.order_by('name').prefetch_related('note')
|
||||
# We match first an alias if it is matched without normalization,
|
||||
# then if the normalized pattern matches a normalized alias.
|
||||
queryset = queryset.filter(
|
||||
Q(name__regex="^" + alias)
|
||||
| Q(normalized_name__regex="^" + Alias.normalize(alias))
|
||||
| Q(normalized_name__regex="^" + alias.lower()))\
|
||||
.order_by('name').prefetch_related('note')
|
||||
name__iregex="^" + alias
|
||||
).union(
|
||||
queryset.filter(
|
||||
Q(normalized_name__iregex="^" + Alias.normalize(alias))
|
||||
& ~Q(name__iregex="^" + alias)
|
||||
),
|
||||
all=True).union(
|
||||
queryset.filter(
|
||||
Q(normalized_name__iregex="^" + alias.lower())
|
||||
& ~Q(normalized_name__iregex="^" + Alias.normalize(alias))
|
||||
& ~Q(name__iregex="^" + alias)
|
||||
),
|
||||
all=True)
|
||||
|
||||
return queryset
|
||||
return queryset.distinct()
|
||||
|
||||
|
||||
class TemplateCategoryViewSet(ReadProtectedModelViewSet):
|
||||
|
|
|
@ -79,7 +79,7 @@ function refreshBalance () {
|
|||
* @param fun For each found note with the matched alias `alias`, fun(note, alias) is called.
|
||||
*/
|
||||
function getMatchedNotes (pattern, fun) {
|
||||
$.getJSON("/api/note/alias/?format=json&alias=" + pattern + "&search=user|club&ordering=normalized_name", fun);
|
||||
$.getJSON("/api/note/alias/?format=json&alias=" + pattern + "&search=user|club", fun);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -261,9 +261,7 @@ function autoCompleteNote (field_id, note_list_id, notes, notes_display, alias_p
|
|||
return;
|
||||
}
|
||||
|
||||
$.getJSON("/api/note/consumer/?format=json&alias="
|
||||
+ pattern
|
||||
+ "&search=user|club&ordering=normalized_name",
|
||||
$.getJSON("/api/note/consumer/?format=json&alias=" + pattern + "&search=user|club",
|
||||
function (consumers) {
|
||||
// The response arrived too late, we stop the request
|
||||
if (pattern !== $("#" + field_id).val())
|
||||
|
|
Loading…
Reference in New Issue