Fixes #2271 -- Added code to imply !__exact on any query argument that doesn't finish with a known query term.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@3248 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2006-07-01 03:14:33 +00:00
parent 4a324ba7ac
commit cd7b54aab0
2 changed files with 23 additions and 2 deletions

View File

@ -10,8 +10,20 @@ import re
if not hasattr(__builtins__, 'set'): if not hasattr(__builtins__, 'set'):
from sets import Set as set from sets import Set as set
# The string constant used to separate query parts
LOOKUP_SEPARATOR = '__' LOOKUP_SEPARATOR = '__'
# The list of valid query types
QUERY_TERMS=(
'exact', 'iexact',
'contains', 'icontains',
'gt', 'gte', 'lt', 'lte',
'in',
'startswith', 'istartswith', 'endswith', 'iendswith',
'range', 'year', 'month', 'day',
'isnull'
)
# Size of each "chunk" for get_iterator calls. # Size of each "chunk" for get_iterator calls.
# Larger values are slightly faster at the expense of more storage space. # Larger values are slightly faster at the expense of more storage space.
GET_ITERATOR_CHUNK_SIZE = 100 GET_ITERATOR_CHUNK_SIZE = 100
@ -710,12 +722,13 @@ def parse_lookup(kwarg_items, opts):
# if we find "pk", make the clause "exact', and insert # if we find "pk", make the clause "exact', and insert
# a dummy name of None, which we will replace when # a dummy name of None, which we will replace when
# we know which table column to grab as the primary key. # we know which table column to grab as the primary key.
# 2) If there is only one part, assume it to be an __exact # 2) If there is only one part, or the last part is not a query
# term, assume that the query is an __exact
clause = path.pop() clause = path.pop()
if clause == 'pk': if clause == 'pk':
clause = 'exact' clause = 'exact'
path.append(None) path.append(None)
elif len(path) == 0: elif len(path) == 0 or clause not in QUERY_TERMS:
path.append(clause) path.append(clause)
clause = 'exact' clause = 'exact'

View File

@ -136,6 +136,10 @@ False
>>> Article.objects.filter(reporter__first_name__exact='John') >>> Article.objects.filter(reporter__first_name__exact='John')
[<Article: John's second story>, <Article: This is a test>] [<Article: John's second story>, <Article: This is a test>]
# Check that implied __exact also works
>>> Article.objects.filter(reporter__first_name='John')
[<Article: John's second story>, <Article: This is a test>]
# Query twice over the related field. # Query twice over the related field.
>>> Article.objects.filter(reporter__first_name__exact='John', reporter__last_name__exact='Smith') >>> Article.objects.filter(reporter__first_name__exact='John', reporter__last_name__exact='Smith')
[<Article: John's second story>, <Article: This is a test>] [<Article: John's second story>, <Article: This is a test>]
@ -237,6 +241,10 @@ TypeError: Cannot resolve keyword 'reporter_id' into field
>>> Reporter.objects.filter(article__reporter__exact=r).distinct() >>> Reporter.objects.filter(article__reporter__exact=r).distinct()
[<Reporter: John Smith>] [<Reporter: John Smith>]
# Check that implied __exact also works
>>> Reporter.objects.filter(article__reporter=r).distinct()
[<Reporter: John Smith>]
# If you delete a reporter, his articles will be deleted. # If you delete a reporter, his articles will be deleted.
>>> Article.objects.all() >>> Article.objects.all()
[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>, <Article: This is a test>, <Article: This is a test>] [<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>, <Article: This is a test>, <Article: This is a test>]