Skip to content

Commit 6e15725

Browse files
authored
Add post_index signal (#349)
* Add `post_index` signal * Add actions to post_index signal * Update post_index_signal test
1 parent 11a7b87 commit 6e15725

File tree

4 files changed

+83
-2
lines changed

4 files changed

+83
-2
lines changed

django_elasticsearch_dsl/documents.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
TextField,
2424
)
2525
from .search import Search
26+
from .signals import post_index
2627

2728
model_field_class_to_field_class = {
2829
models.AutoField: IntegerField,
@@ -144,7 +145,15 @@ def to_field(cls, field_name, model_field):
144145
)
145146

146147
def bulk(self, actions, **kwargs):
147-
return bulk(client=self._get_connection(), actions=actions, **kwargs)
148+
response = bulk(client=self._get_connection(), actions=actions, **kwargs)
149+
# send post index signal
150+
post_index.send(
151+
sender=self.__class__,
152+
instance=self,
153+
actions=actions,
154+
response=response
155+
)
156+
return response
148157

149158
def parallel_bulk(self, actions, **kwargs):
150159
if self.django.queryset_pagination and 'chunk_size' not in kwargs:

django_elasticsearch_dsl/signals.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from __future__ import absolute_import
88

99
from django.db import models
10+
from django.dispatch import Signal
1011

1112
from .registries import registry
1213

@@ -94,3 +95,7 @@ def teardown(self):
9495
models.signals.post_delete.disconnect(self.handle_delete)
9596
models.signals.m2m_changed.disconnect(self.handle_m2m_changed)
9697
models.signals.pre_delete.disconnect(self.handle_pre_delete)
98+
99+
100+
# Sent after document indexing is completed
101+
post_index = Signal()

docs/source/es_index.rst

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Index
2-
######
2+
#####
33

44
In typical scenario using `class Index` on a `Document` class is sufficient to perform any action.
55
In a few cases though it can be useful to manipulate an Index object directly.
@@ -60,3 +60,25 @@ in Elasticsearch with appropriate mapping.
6060
** If your model have huge amount of data, its preferred to use `parallel` indexing.
6161
To do that, you can pass `--parallel` flag while reindexing or populating.
6262
**
63+
64+
65+
Signals
66+
=======
67+
68+
* ``django_elasticsearch_dsl.signals.post_index``
69+
Sent after document indexing is completed. (not applicable for ``parallel`` indexing).
70+
Provides the following arguments:
71+
72+
``sender``
73+
A subclass of ``django_elasticsearch_dsl.documents.DocType`` used
74+
to perform indexing.
75+
76+
``instance``
77+
A ``django_elasticsearch_dsl.documents.DocType`` subclass instance.
78+
79+
``actions``
80+
A generator containing document data that were sent to elasticsearch for indexing.
81+
82+
``response``
83+
The response from ``bulk()`` function of ``elasticsearch-py``,
84+
which includes ``success`` count and ``failed`` count or ``error`` list.

tests/test_signals.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from unittest import TestCase
2+
3+
from mock import Mock, patch
4+
5+
from django_elasticsearch_dsl.documents import DocType
6+
from django_elasticsearch_dsl.registries import registry
7+
from django_elasticsearch_dsl.signals import post_index
8+
9+
from .models import Car
10+
11+
12+
class PostIndexSignalTestCase(TestCase):
13+
14+
@patch('django_elasticsearch_dsl.documents.DocType._get_actions')
15+
@patch('django_elasticsearch_dsl.documents.bulk')
16+
def test_post_index_signal_sent(self, bulk, get_actions):
17+
18+
@registry.register_document
19+
class CarDocument(DocType):
20+
class Django:
21+
fields = ['name']
22+
model = Car
23+
24+
bulk.return_value = (1, [])
25+
26+
# register a mock signal receiver
27+
mock_receiver = Mock()
28+
post_index.connect(mock_receiver)
29+
30+
doc = CarDocument()
31+
car = Car(
32+
pk=51,
33+
name="Type 57"
34+
)
35+
doc.update(car)
36+
37+
bulk.assert_called_once()
38+
39+
mock_receiver.assert_called_once_with(
40+
signal=post_index,
41+
sender=CarDocument,
42+
instance=doc,
43+
actions=get_actions(),
44+
response=(1, [])
45+
)

0 commit comments

Comments
 (0)