Skip to content

Commit 6264347

Browse files
committed
refactor: Refactor ChangelistView to match latest Django implementation
1 parent da5f2b5 commit 6264347

File tree

2 files changed

+53
-27
lines changed

2 files changed

+53
-27
lines changed

django_mongoengine/mongo_admin/options.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
from functools import partial, partialmethod
1+
import operator
2+
from functools import partial, partialmethod, reduce
23

34
from django import forms
45
from django.apps import apps
56
from django.conf import settings
67
from django.contrib.admin import helpers, widgets
78
from django.contrib.admin.exceptions import DisallowedModelAdminToField
8-
from django.contrib.admin.options import IS_POPUP_VAR, TO_FIELD_VAR, csrf_protect_m, get_ul_class
9+
from django.contrib.admin.options import (
10+
IS_POPUP_VAR,
11+
TO_FIELD_VAR,
12+
csrf_protect_m,
13+
get_ul_class,
14+
)
915
from django.contrib.admin.utils import flatten_fieldsets, get_deleted_objects, unquote
1016
from django.core.exceptions import PermissionDenied
1117
from django.forms.formsets import all_valid
@@ -18,8 +24,14 @@
1824
from django.utils.html import escape
1925
from django.utils.text import capfirst
2026
from django.utils.translation import gettext as _
27+
from mongoengine import Q
2128

22-
from django_mongoengine.fields import EmbeddedDocumentField, ListField, ReferenceField, StringField
29+
from django_mongoengine.fields import (
30+
EmbeddedDocumentField,
31+
ListField,
32+
ReferenceField,
33+
StringField,
34+
)
2335
from django_mongoengine.forms.documents import (
2436
BaseInlineDocumentFormSet,
2537
DocumentForm,
@@ -234,6 +246,36 @@ def get_changelist_formset(self, request, **kwargs):
234246
**defaults
235247
)
236248

249+
def get_search_results(self, request, queryset, search_term):
250+
"""
251+
Return a tuple containing a queryset to implement the search
252+
and a boolean indicating if the results may contain duplicates.
253+
"""
254+
255+
def construct_search(field_name):
256+
if field_name.startswith('^'):
257+
return "%s__istartswith" % field_name[1:]
258+
elif field_name.startswith('='):
259+
return "%s__iexact" % field_name[1:]
260+
# No __search for mongoengine
261+
# elif field_name.startswith('@'):
262+
# return "%s__search" % field_name[1:]
263+
else:
264+
return "%s__icontains" % field_name
265+
266+
search_fields = self.get_search_fields(request)
267+
268+
if search_fields and search_term:
269+
orm_lookups = [
270+
construct_search(str(search_field)) for search_field in search_fields
271+
]
272+
for bit in search_term.split():
273+
or_queries = [Q(**{orm_lookup: bit}) for orm_lookup in orm_lookups]
274+
queryset = queryset.filter(reduce(operator.or_, or_queries))
275+
276+
return queryset, False
277+
278+
237279
def get_changelist(self, request, **kwargs):
238280
"""
239281
Returns the ChangeList class for use on the changelist page.

django_mongoengine/mongo_admin/views.py

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
import operator
2-
from functools import reduce
3-
41
from django.contrib.admin.options import IncorrectLookupParameters
52
from django.contrib.admin.views.main import ORDER_VAR, ChangeList
63
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
74
from django.core.paginator import InvalidPage
8-
from mongoengine import Q
95

106

117
class DocumentChangeList(ChangeList):
@@ -114,7 +110,7 @@ def get_queryset(self, request=None):
114110
self.filter_specs,
115111
self.has_filters,
116112
remaining_lookup_params,
117-
use_distinct,
113+
search_may_have_duplicates,
118114
has_active_filters,
119115
) = self.get_filters(request)
120116

@@ -146,23 +142,11 @@ def get_queryset(self, request=None):
146142
ordering = self.get_ordering(request, qs)
147143
qs = qs.order_by(*ordering)
148144

149-
# Apply keyword searches.
150-
def construct_search(field_name):
151-
if field_name.startswith('^'):
152-
return "%s__istartswith" % field_name[1:]
153-
elif field_name.startswith('='):
154-
return "%s__iexact" % field_name[1:]
155-
# No __search for mongoengine
156-
# elif field_name.startswith('@'):
157-
# return "%s__search" % field_name[1:]
158-
else:
159-
return "%s__icontains" % field_name
160-
161-
if self.search_fields and self.query:
162-
orm_lookups = [
163-
construct_search(str(search_field)) for search_field in self.search_fields
164-
]
165-
for bit in self.query.split():
166-
or_queries = [Q(**{orm_lookup: bit}) for orm_lookup in orm_lookups]
167-
qs = qs.filter(reduce(operator.or_, or_queries))
145+
# Apply search results
146+
qs, search_may_have_duplicates = self.model_admin.get_search_results(
147+
request,
148+
qs,
149+
self.query,
150+
)
151+
168152
return qs

0 commit comments

Comments
 (0)