Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BDE
Note Kfet 2018
Commits
d361fbde
Commit
d361fbde
authored
Aug 28, 2018
by
Hamza Dely
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[consos/views] Utilisation d'un filtre modifié pour la recherche dans les notes
parent
00129cb0
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
99 additions
and
11 deletions
+99
-11
consos/views.py
consos/views.py
+21
-11
note_kfet/filters.py
note_kfet/filters.py
+64
-0
note_kfet/utils.py
note_kfet/utils.py
+14
-0
No files found.
consos/views.py
View file @
d361fbde
...
...
@@ -2,6 +2,7 @@
Vues de l'application « Consos »
"""
import
django
from
django.urls
import
reverse_lazy
from
django.shortcuts
import
get_object_or_404
from
django.contrib
import
messages
...
...
@@ -13,7 +14,7 @@ from django.views.generic.edit import FormView, CreateView, UpdateView
from
django.contrib.auth.mixins
import
LoginRequiredMixin
,
PermissionRequiredMixin
from
django.contrib.contenttypes.models
import
ContentType
from
rest_framework
import
viewsets
,
status
,
filters
from
rest_framework
import
viewsets
,
status
from
rest_framework.response
import
Response
from
rest_framework.decorators
import
detail_route
...
...
@@ -21,6 +22,7 @@ from django_filters.rest_framework import DjangoFilterBackend
from
note_kfet.utils
import
to_bool
from
note_kfet.droits
import
D
,
Acl
from
note_kfet.filters
import
NoteSearchFilter
from
note_kfet.views.mixins
import
NoteMixin
from
note_kfet.views.decorators
import
requires
...
...
@@ -313,8 +315,8 @@ class NoteViewSet(viewsets.GenericViewSet):
"""
queryset
=
Note
.
objects
.
all
()
serializer_class
=
NoteSerializer
filter_backends
=
(
filters
.
SearchFilter
,)
search_fields
=
(
'
$
alias'
,)
filter_backends
=
(
Note
SearchFilter
,)
search_fields
=
(
'alias'
,)
@
requires
(
"comptes.adherent_chercher"
,
Acl
.
BASIQUE
)
def
list
(
self
,
request
):
...
...
@@ -341,14 +343,22 @@ class NoteViewSet(viewsets.GenericViewSet):
)
qs
=
qs
.
select_related
(
'proprietaire__note'
)
data
=
[
{
'alias'
:
alias
.
alias
,
'pseudo'
:
alias
.
proprietaire
.
pseudo
,
'solde'
:
alias
.
proprietaire
.
note
.
solde
,
'adherent'
:
alias
.
proprietaire
.
note
.
adherent
,
}
for
alias
in
qs
]
try
:
data
=
[
{
'alias'
:
alias
.
alias
,
'pseudo'
:
alias
.
proprietaire
.
pseudo
,
'solde'
:
alias
.
proprietaire
.
note
.
solde
,
'adherent'
:
alias
.
proprietaire
.
note
.
adherent
,
}
for
alias
in
qs
]
except
django
.
db
.
DataError
as
e
:
return
Response
(
{
"detail"
:
"%s"
%
e
.
args
,
},
status
=
status
.
HTTP_400_BAD_REQUEST
,
)
fields
=
[
'adherent'
,
'pseudo'
,
'alias'
,
'solde'
]
serializer
=
self
.
get_serializer
(
data
,
fields
=
fields
,
many
=
True
)
return
Response
(
serializer
.
data
,
status
=
status
.
HTTP_200_OK
)
...
...
note_kfet/filters.py
0 → 100644
View file @
d361fbde
"""
Filtres spéciaux pour la Note Kfet
"""
import
operator
from
functools
import
reduce
from
distutils.util
import
strtobool
from
django.db
import
models
from
django.db.models.constants
import
LOOKUP_SEP
from
rest_framework
import
filters
from
rest_framework.compat
import
distinct
from
note_kfet.utils
import
escape_regex
class
NoteSearchFilter
(
filters
.
SearchFilter
):
"""
Filtre de recherche permettant d'effectuer au choix
une recherche brute ou une recherche par expression régulière
en commençant à chercher au début d'un mot
"""
def
get_regex_mode
(
self
,
request
):
return
strtobool
(
request
.
query_params
.
get
(
'regex'
,
'false'
))
def
construct_search
(
self
,
field_name
):
return
LOOKUP_SEP
.
join
([
field_name
,
'iregex'
])
def
filter_queryset
(
self
,
request
,
queryset
,
view
):
search_fields
=
getattr
(
view
,
'search_fields'
,
None
)
use_regex_mode
=
self
.
get_regex_mode
(
request
)
search_terms
=
self
.
get_search_terms
(
request
)
if
not
search_fields
or
not
search_terms
:
return
queryset
search_terms
=
[
"^%s"
%
(
search_term
if
use_regex_mode
else
escape_regex
(
search_term
)
)
for
search_term
in
search_terms
]
orm_lookups
=
[
self
.
construct_search
(
search_field
)
for
search_field
in
search_fields
]
base
=
queryset
conditions
=
[]
for
search_term
in
search_terms
:
queries
=
[
models
.
Q
(
**
{
orm_lookup
:
search_term
})
for
orm_lookup
in
orm_lookups
]
conditions
.
append
(
reduce
(
operator
.
or_
,
queries
))
queryset
=
queryset
.
filter
(
reduce
(
operator
.
and_
,
conditions
))
if
self
.
must_call_distinct
(
queryset
,
search_fields
):
# Filtering against a many-to-many field requires us to
# call queryset.distinct() in order to avoid duplicate items
# in the resulting queryset.
# We try to avoid this if possible, for performance reasons.
queryset
=
distinct
(
queryset
,
base
)
return
queryset
note_kfet/utils.py
View file @
d361fbde
...
...
@@ -53,3 +53,17 @@ def to_bool(value):
return
bool
(
strtobool
(
value
))
except
ValueError
:
return
None
def
escape_regex
(
regex
):
"""
Échappe les caractères spéciaux utilisés dans les expressions
régulières POSIX (PREs)
"""
escaped
=
""
for
char
in
regex
:
if
char
in
[
'{'
,
'}'
,
'('
,
')'
,
'['
,
']'
,
'|'
,
'?'
,
'*'
,
'.'
,
'
\\
'
,]:
escaped
+=
'
\\
'
+
char
else
:
escaped
+=
char
return
escaped
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment