Fixed #2559 -- Added cool new operators for Admin.search_fields, plus documentation. Thanks, Andy Dustman.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@3601 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
eefe35c7fa
commit
efa19ae8a7
1
AUTHORS
1
AUTHORS
|
@ -68,6 +68,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
deric@monowerks.com
|
||||
dne@mayonnaise.net
|
||||
Jeremy Dunck <http://dunck.us/>
|
||||
Andy Dustman <farcepest@gmail.com>
|
||||
Clint Ecker
|
||||
gandalf@owca.info
|
||||
Baishampayan Ghose
|
||||
|
|
|
@ -711,9 +711,19 @@ class ChangeList(object):
|
|||
qs = qs.order_by((self.order_type == 'desc' and '-' or '') + lookup_order_field)
|
||||
|
||||
# Apply keyword searches.
|
||||
def construct_search(field_name):
|
||||
if field_name.startswith('^'):
|
||||
return "%s__istartswith" % field_name[1:]
|
||||
elif field_name.startswith('='):
|
||||
return "%s__iexact" % field_name[1:]
|
||||
elif field_name.startswith('@'):
|
||||
return "%s__search" % field_name[1:]
|
||||
else:
|
||||
return "%s__icontains" % field_name
|
||||
|
||||
if self.lookup_opts.admin.search_fields and self.query:
|
||||
for bit in self.query.split():
|
||||
or_queries = [models.Q(**{'%s__icontains' % field_name: bit}) for field_name in self.lookup_opts.admin.search_fields]
|
||||
or_queries = [models.Q(**{construct_search(field_name): bit}) for field_name in self.lookup_opts.admin.search_fields]
|
||||
other_qs = QuerySet(self.model)
|
||||
other_qs = other_qs.filter(reduce(operator.or_, or_queries))
|
||||
qs = qs & other_qs
|
||||
|
|
|
@ -1386,6 +1386,41 @@ user searches for ``john lennon``, Django will do the equivalent of this SQL
|
|||
WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
|
||||
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
|
||||
|
||||
**New in Django development version:** For faster and/or more restrictive
|
||||
searches, prefix the field name with an operator:
|
||||
|
||||
``^``
|
||||
Matches the beginning of the field. For example, if ``search_fields`` is
|
||||
set to ``['^first_name', '^last_name']`` and a user searches for
|
||||
``john lennon``, Django will do the equivalent of this SQL ``WHERE``
|
||||
clause::
|
||||
|
||||
WHERE (first_name ILIKE 'john%' OR last_name ILIKE 'john%')
|
||||
AND (first_name ILIKE 'lennon%' OR last_name ILIKE 'lennon%')
|
||||
|
||||
This query is more efficient than the normal ``'%john%'`` query, because
|
||||
the database only needs to check the beginning of a column's data, rather
|
||||
than seeking through the entire column's data. Plus, if the column has an
|
||||
index on it, some databases may be able to use the index for this query,
|
||||
even though it's a ``LIKE`` query.
|
||||
|
||||
``=``
|
||||
Matches exactly, case-insensitive. For example, if
|
||||
``search_fields`` is set to ``['=first_name', '=last_name']`` and
|
||||
a user searches for ``john lennon``, Django will do the equivalent
|
||||
of this SQL ``WHERE`` clause::
|
||||
|
||||
WHERE (first_name ILIKE 'john' OR last_name ILIKE 'john')
|
||||
AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')
|
||||
|
||||
Note that the query input is split by spaces, so, following this example,
|
||||
it's not currently not possible to search for all records in which
|
||||
``first_name`` is exactly ``'john winston'`` (containing a space).
|
||||
|
||||
``@``
|
||||
Performs a full-text match. This is like the default search method but uses
|
||||
an index. Currently this is only available for MySQL.
|
||||
|
||||
Managers
|
||||
========
|
||||
|
||||
|
|
Loading…
Reference in New Issue