Skip to content

Commit e55d524

Browse files
carljmtoastdriven
authored andcommitted
Don't assume that any pk castable to an integer should be an integer.
1 parent 1b47512 commit e55d524

File tree

6 files changed

+50
-17
lines changed

6 files changed

+50
-17
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ Thanks to
4545
* ghostrocket for a patch regarding the simple backend.
4646
* Rob Hudson (robhudson) for improvements to the admin search.
4747
* apollo13 for simplifying ``SearchForm.__init__``.
48+
* Carl Meyer (carljm) for a patch regarding character primary keys.

haystack/query.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,16 @@ def _fill_cache(self, start, end):
160160

161161
for result in results:
162162
if self._load_all:
163-
# We have to deal with integer keys being cast from strings; if this
164-
# fails we've got a character pk.
165-
try:
166-
result.pk = int(result.pk)
167-
except ValueError:
168-
pass
163+
# We have to deal with integer keys being cast from strings
164+
model_objects = loaded_objects.get(result.model, {})
165+
if not result.pk in model_objects:
166+
try:
167+
result.pk = int(result.pk)
168+
except ValueError:
169+
pass
169170
try:
170-
result._object = loaded_objects[result.model][result.pk]
171-
except (KeyError, IndexError):
171+
result._object = model_objects[result.pk]
172+
except KeyError:
172173
# The object was either deleted since we indexed or should
173174
# be ignored; fail silently.
174175
self._ignored_result_count += 1

tests/core/fixtures/initial_data.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,17 @@
4242
"pub_date": "2009-03-17 08:00:00",
4343
"tag": 2
4444
}
45+
},
46+
{
47+
"pk": "sometext",
48+
"model": "core.charpkmockmodel",
49+
"fields": {
50+
}
51+
},
52+
{
53+
"pk": "1234",
54+
"model": "core.charpkmockmodel",
55+
"fields": {
56+
}
4557
}
4658
]

tests/core/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,7 @@ def __unicode__(self):
3131
class AThirdMockModel(AnotherMockModel):
3232
average_delay = models.FloatField(default=0.0)
3333
view_count = models.PositiveIntegerField(default=0)
34+
35+
36+
class CharPKMockModel(models.Model):
37+
key = models.CharField(primary_key=True, max_length=10)

tests/core/tests/mocks.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
class MockSearchResult(SearchResult):
1010
def __init__(self, app_label, model_name, pk, score, **kwargs):
1111
super(MockSearchResult, self).__init__(app_label, model_name, pk, score, **kwargs)
12-
self._model = MockModel
13-
12+
self._model = get_model('core', model_name)
1413

1514
MOCK_SEARCH_RESULTS = [MockSearchResult('core', 'MockModel', i, 1 - (i / 100.0)) for i in xrange(100)]
1615

1716

1817
class MockSearchBackend(BaseSearchBackend):
18+
model_name = 'mockmodel'
19+
mock_search_results = MOCK_SEARCH_RESULTS
20+
1921
def __init__(self, site=None):
2022
self.docs = {}
2123
self.site = site
@@ -38,13 +40,13 @@ def search(self, query_string, sort_by=None, start_offset=0, end_offset=None,
3840
limit_to_registered_models=None, **kwargs):
3941
from haystack import site
4042
results = []
41-
hits = len(MOCK_SEARCH_RESULTS)
43+
hits = len(self.mock_search_results)
4244
indexed_models = site.get_indexed_models()
4345

44-
sliced = MOCK_SEARCH_RESULTS[start_offset:end_offset]
46+
sliced = self.mock_search_results[start_offset:end_offset]
4547

4648
for result in sliced:
47-
model = get_model('core', 'mockmodel')
49+
model = get_model('core', self.model_name)
4850

4951
if model:
5052
if model in indexed_models:
@@ -61,11 +63,16 @@ def search(self, query_string, sort_by=None, start_offset=0, end_offset=None,
6163

6264
def more_like_this(self, model_instance, additional_query_string=None):
6365
return {
64-
'results': MOCK_SEARCH_RESULTS,
65-
'hits': len(MOCK_SEARCH_RESULTS),
66+
'results': self.mock_search_results,
67+
'hits': len(self.mock_search_results),
6668
}
6769

6870

71+
class CharPKMockSearchBackend(MockSearchBackend):
72+
model_name = 'charpkmockmodel'
73+
mock_search_results = [MockSearchResult('core', 'CharPKMockModel', 'sometext', 0.5),
74+
MockSearchResult('core', 'CharPKMockModel', '1234', 0.3)]
75+
6976
class MixedMockSearchBackend(MockSearchBackend):
7077
@log_query
7178
def search(self, query_string, **kwargs):

tests/core/tests/query.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
from haystack.models import SearchResult
1212
from haystack.query import SearchQuerySet, EmptySearchQuerySet
1313
from haystack.sites import SearchSite
14-
from core.models import MockModel, AnotherMockModel
15-
from core.tests.mocks import MockSearchQuery, MockSearchBackend, MixedMockSearchBackend, MOCK_SEARCH_RESULTS
14+
from core.models import MockModel, AnotherMockModel, CharPKMockModel
15+
from core.tests.mocks import MockSearchQuery, MockSearchBackend, CharPKMockSearchBackend, MixedMockSearchBackend, MOCK_SEARCH_RESULTS
1616
try:
1717
set
1818
except NameError:
@@ -284,6 +284,7 @@ def setUp(self):
284284
self.old_site = haystack.site
285285
test_site = SearchSite()
286286
test_site.register(MockModel)
287+
test_site.register(CharPKMockModel)
287288
haystack.site = test_site
288289

289290
backends.reset_search_queries()
@@ -468,6 +469,13 @@ def test_raw_search(self):
468469
self.assertEqual(len(self.bsqs.raw_search('(content__exact hello AND content__exact world)')), 1)
469470

470471
def test_load_all(self):
472+
# Models with character primary keys
473+
sqs = SearchQuerySet(query=MockSearchQuery(backend=CharPKMockSearchBackend()))
474+
results = sqs.load_all().all()
475+
self.assertEqual(len(results._result_cache), 0)
476+
results._fill_cache(0, 2)
477+
self.assertEqual(len([result for result in results._result_cache if result is not None]), 2)
478+
471479
# If nothing is registered, you get nothing.
472480
haystack.site.unregister(MockModel)
473481
sqs = self.msqs.load_all()

0 commit comments

Comments
 (0)