8
8
9
9
from flask import request , abort
10
10
from flask_login import current_user
11
- from sqlalchemy .sql import text
11
+ from sqlalchemy .orm import Query
12
12
from sqlalchemy import func , and_
13
13
from marshmallow import fields
14
14
@@ -31,39 +31,18 @@ class Meta:
31
31
fields = (
32
32
"id" ,
33
33
"full_name" ,
34
- "license_expiry_date " ,
34
+ "is_active " ,
35
35
)
36
36
37
37
38
- def find_users_by_fuzzy_name (pattern , limit = 8 ) :
39
- """Find user for autocomplete from a part of their full name.
38
+ def _make_autocomplete_query (pattern : str ) -> Query :
39
+ """Builds the autocomplete query for the provided pattern"""
40
40
41
- Comparison are case insensitive.
41
+ query = db .session .query (User )
42
+ query = query .filter (func .lower (User .full_name ()).like (f"%{ pattern } %" ))
43
+ query = query .order_by (User .is_active .desc (), User .full_name (), User .id )
42
44
43
- :param string pattern: Part of the name that will be searched.
44
- :param int limit: Maximum number of response.
45
- :return: List of users corresponding to ``pattern``
46
- :rtype: list(:py:class:`collectives.models.user.User`)
47
- """
48
- if "sqlite" in db .engine .name :
49
- # SQLlite does not follow SQL standard
50
- concat_clause = "(first_name || ' ' || last_name)"
51
- else :
52
- concat_clause = "CONCAT(first_name, ' ', last_name)"
53
-
54
- sql = (
55
- f"SELECT id, first_name, last_name from users WHERE "
56
- f"LOWER({ concat_clause } ) LIKE :pattern LIMIT :limit"
57
- )
58
-
59
- sql_pattern = f"%{ pattern .lower ()} %"
60
- found_users = (
61
- db .session .query (User )
62
- .from_statement (text (sql ))
63
- .params (pattern = sql_pattern , limit = limit )
64
- )
65
-
66
- return found_users
45
+ return query
67
46
68
47
69
48
@blueprint .route ("/users/autocomplete/create_rental" )
@@ -90,8 +69,8 @@ def autocomplete_users_create_rental():
90
69
if pattern is None or (len (pattern ) < 2 ):
91
70
found_users = []
92
71
else :
93
- limit = request .args .get ("l" , type = int ) or 8
94
- found_users = find_users_by_fuzzy_name (pattern , limit )
72
+ limit = request .args .get ("l" , default = 8 , type = int )
73
+ found_users = _make_autocomplete_query (pattern ). limit ( limit )
95
74
96
75
content = json .dumps (AutocompleteUserSchema (many = True ).dump (found_users ))
97
76
return content , 200 , {"content-type" : "application/json" }
@@ -121,8 +100,8 @@ def autocomplete_users():
121
100
if pattern is None or (len (pattern ) < 2 ):
122
101
found_users = []
123
102
else :
124
- limit = request .args .get ("l" , type = int ) or 8
125
- found_users = find_users_by_fuzzy_name (pattern , limit )
103
+ limit = request .args .get ("l" , default = 8 , type = int )
104
+ found_users = _make_autocomplete_query (pattern ). limit ( limit )
126
105
127
106
content = json .dumps (AutocompleteUserSchema (many = True ).dump (found_users ))
128
107
return content , 200 , {"content-type" : "application/json" }
@@ -148,16 +127,11 @@ def autocomplete_leaders():
148
127
if len (pattern ) < 2 :
149
128
found_users = []
150
129
else :
151
- limit = request .args .get ("l" , type = int ) or 8
130
+ limit = request .args .get ("l" , default = 8 , type = int )
152
131
153
- query = db .session .query (User )
154
- condition = func .lower (User .first_name + " " + User .last_name ).like (
155
- f"%{ pattern } %"
156
- )
157
- query = query .filter (condition )
132
+ query = _make_autocomplete_query (pattern )
158
133
query = query .filter (User .led_events )
159
- found_users = query .order_by (User .id ).all ()
160
- found_users = found_users [0 :limit ]
134
+ found_users = query .limit (limit )
161
135
162
136
content = json .dumps (AutocompleteUserSchema (many = True ).dump (found_users ))
163
137
return content , 200 , {"content-type" : "application/json" }
@@ -188,15 +162,15 @@ def autocomplete_available_leaders():
188
162
if pattern is None or (len (pattern ) < 2 ):
189
163
found_users = []
190
164
else :
191
- limit = request .args .get ("l" , type = int ) or 8
165
+ limit = request .args .get ("l" , default = 8 , type = int )
166
+
167
+ query = _make_autocomplete_query (pattern )
192
168
event_type = db .session .get (
193
169
EventType , request .args .get ("etype" , type = int , default = 0 )
194
170
)
195
171
activity_ids = request .args .getlist ("aid" , type = int )
196
172
existing_ids = request .args .getlist ("eid" , type = int )
197
173
198
- query = db .session .query (User )
199
-
200
174
if event_type and event_type .requires_activity :
201
175
ok_roles = RoleIds .all_activity_leader_roles ()
202
176
else :
@@ -206,12 +180,7 @@ def autocomplete_available_leaders():
206
180
role_condition = and_ (role_condition , Role .activity_id .in_ (activity_ids ))
207
181
query = query .filter (User .roles .any (role_condition ))
208
182
query = query .filter (~ User .id .in_ (existing_ids ))
209
- condition = func .lower (User .first_name + " " + User .last_name ).ilike (
210
- f"%{ pattern } %"
211
- )
212
- query = query .filter (condition )
213
183
214
- query = query .order_by (User .first_name , User .last_name , User .id )
215
184
found_users = query .limit (limit )
216
185
217
186
content = json .dumps (AutocompleteUserSchema (many = True ).dump (found_users ))
0 commit comments