|
1 | 1 | # "Hey, Django! Look at me, I'm an app! For Serious!"
|
2 | 2 | import logging
|
| 3 | +from django.conf import settings |
3 | 4 | from django.core.exceptions import ObjectDoesNotExist
|
4 | 5 | from django.db import models
|
5 | 6 | from django.utils.encoding import force_unicode
|
@@ -221,11 +222,46 @@ def __setstate__(self, data_dict):
|
221 | 222 |
|
222 | 223 | # Setup pre_save/pre_delete signals to make sure things like the signals in
|
223 | 224 | # ``RealTimeSearchIndex`` are setup in time to handle data changes.
|
224 |
| -def load_indexes(sender, instance, *args, **kwargs): |
| 225 | +def load_indexes(sender, *args, **kwargs): |
225 | 226 | from haystack import connections
|
226 | 227 |
|
227 | 228 | for conn in connections.all():
|
228 |
| - conn.get_unified_index().setup_indexes() |
| 229 | + ui = conn.get_unified_index() |
| 230 | + ui.setup_indexes() |
| 231 | + |
| 232 | + |
| 233 | +def reload_indexes(sender, *args, **kwargs): |
| 234 | + from haystack import connections |
| 235 | + |
| 236 | + for conn in connections.all(): |
| 237 | + ui = conn.get_unified_index() |
| 238 | + # Note: Unlike above, we're resetting the ``UnifiedIndex`` here. |
| 239 | + # Thi gives us a clean slate. |
| 240 | + ui.reset() |
| 241 | + ui.setup_indexes() |
| 242 | + |
229 | 243 |
|
230 | 244 | models.signals.pre_save.connect(load_indexes, dispatch_uid='setup_index_signals')
|
231 | 245 | models.signals.pre_delete.connect(load_indexes, dispatch_uid='setup_index_signals')
|
| 246 | + |
| 247 | + |
| 248 | +if 'south' in settings.INSTALLED_APPS: |
| 249 | + # South causes a little mayhem, as when you run a ``syncdb``, it'll setup |
| 250 | + # the apps *without* migrations using Django's built-in ``syncdb``. When |
| 251 | + # this happens, ``INSTALLED_APPS`` consists of only those apps, NOT all |
| 252 | + # apps.At the end of that sync, Django runs ``create_permissions``, which |
| 253 | + # of course uses the ORM, causing the ``pre_save`` above to fire. |
| 254 | + |
| 255 | + # The effect is that Haystack runs its setup against the then-subset of |
| 256 | + # ``INSTALLED_APPS``. Once that's done, it won't re-setup the |
| 257 | + # ``UnifiedIndex`` again, since the signal has a ``dispatch_uid``. |
| 258 | + |
| 259 | + # This bug gets exposed only either when people run tests that *use* |
| 260 | + # the South migrations OR when they have a data migration & the changed |
| 261 | + # data isn't picked up by ``RealTimeSearchIndex`` (or similar). |
| 262 | + |
| 263 | + # In the event of this, the only safe route is to listen for |
| 264 | + # ``south.signals.post_migrate``, then re-run setup. This will |
| 265 | + # unfortunately happen per-app, but should be quick & reliable. |
| 266 | + from south.signals import post_migrate |
| 267 | + post_migrate.connect(reload_indexes) |
0 commit comments