|
46 | 46 | :parts: 1
|
47 | 47 |
|
48 | 48 | """
|
49 |
| -import re |
| 49 | +import operator |
50 | 50 | import uuid
|
| 51 | +from functools import reduce |
51 | 52 | from itertools import chain
|
52 | 53 | from pickle import PicklingError # nosec
|
53 | 54 |
|
54 | 55 | from django import forms
|
| 56 | +from django.contrib.admin.utils import lookup_needs_distinct |
55 | 57 | from django.contrib.admin.widgets import SELECT2_TRANSLATIONS
|
56 | 58 | from django.core import signing
|
57 | 59 | from django.db.models import Q
|
@@ -315,8 +317,6 @@ class HeavySelect2TagWidget(HeavySelect2Mixin, Select2TagWidget):
|
315 | 317 | class ModelSelect2Mixin:
|
316 | 318 | """Widget mixin that provides attributes and methods for :class:`.AutoResponseView`."""
|
317 | 319 |
|
318 |
| - _word_split_pattern = re.compile(r"\t|\n| ") |
319 |
| - |
320 | 320 | model = None
|
321 | 321 | queryset = None
|
322 | 322 | search_fields = []
|
@@ -400,19 +400,24 @@ def filter_queryset(self, request, term, queryset=None, **dependent_fields):
|
400 | 400 | search_fields = self.get_search_fields()
|
401 | 401 | select = Q()
|
402 | 402 |
|
403 |
| - if term != "": |
404 |
| - for field in search_fields: |
405 |
| - field_select = Q(**{field: term}) |
406 |
| - if "contains" in field: |
407 |
| - for word in filter(None, self._word_split_pattern.split(term)): |
408 |
| - field_select |= Q(**{field: word}) |
409 |
| - |
410 |
| - select |= field_select |
| 403 | + use_distinct = False |
| 404 | + if search_fields and term: |
| 405 | + for bit in term.split(): |
| 406 | + or_queries = [Q(**{orm_lookup: bit}) for orm_lookup in search_fields] |
| 407 | + select &= reduce(operator.or_, or_queries) |
| 408 | + or_queries = [Q(**{orm_lookup: term}) for orm_lookup in search_fields] |
| 409 | + select |= reduce(operator.or_, or_queries) |
| 410 | + use_distinct |= any( |
| 411 | + lookup_needs_distinct(queryset.model._meta, search_spec) |
| 412 | + for search_spec in search_fields |
| 413 | + ) |
411 | 414 |
|
412 | 415 | if dependent_fields:
|
413 | 416 | select &= Q(**dependent_fields)
|
414 | 417 |
|
415 |
| - return queryset.filter(select).distinct() |
| 418 | + if use_distinct: |
| 419 | + queryset.filter(select).distinct() |
| 420 | + return queryset.filter(select) |
416 | 421 |
|
417 | 422 | def get_queryset(self):
|
418 | 423 | """
|
|
0 commit comments