Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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
  • Loading branch information...
commit efa19ae8a78d555e826dc7bbbfa1c20c3475e498 1 parent eefe35c
@adrianholovaty adrianholovaty authored
Showing with 52 additions and 6 deletions.
  1. +1 −0  AUTHORS
  2. +11 −1 django/contrib/admin/views/main.py
  3. +40 −5 docs/model-api.txt
View
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
View
12 django/contrib/admin/views/main.py
@@ -711,9 +711,19 @@ def get_query_set(self):
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
View
45 docs/model-api.txt
@@ -686,8 +686,8 @@ you can use the name of the model, rather than the model object itself::
class Manufacturer(models.Model):
# ...
-Note, however, that you can only use strings to refer to models in the same
-models.py file -- you cannot use a string to reference a model in a different
+Note, however, that you can only use strings to refer to models in the same
+models.py file -- you cannot use a string to reference a model in a different
application, or to reference a model that has been imported from elsewhere.
Behind the scenes, Django appends ``"_id"`` to the field name to create its
@@ -810,9 +810,9 @@ here's how you'd represent that::
As with ``ForeignKey``, a relationship to self can be defined by using the
string ``'self'`` instead of the model name, and you can refer to as-yet
-undefined models by using a string containing the model name. However, you
-can only use strings to refer to models in the same models.py file -- you
-cannot use a string to reference a model in a different application, or to
+undefined models by using a string containing the model name. However, you
+can only use strings to refer to models in the same models.py file -- you
+cannot use a string to reference a model in a different application, or to
reference a model that has been imported from elsewhere.
It's suggested, but not required, that the name of a ``ManyToManyField``
@@ -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
========
Please sign in to comment.
Something went wrong with that request. Please try again.