liberation / django-elasticsearch

Simple wrapper around elasticsearch-py to index/search a django Model.
MIT License
212 stars 73 forks source link

Update index when M2M field changed #66

Closed yarnball closed 7 years ago

yarnball commented 7 years ago

Hi,

Great work on this project.

I have am indexing an Item field which points to Many Tag items as a ManyToMany relationship.

When I add, move, or delete a Tag- it does not update the ES index.

I attempted to create a m2m_changed signal, however it had no affect.

When I add an M2M to Item, or remove one, it only saves when I press save twice (ie re-enter the model).

How can I signal to update the index on an M2M? And also, how would I tell it to keep track of changes in the Tag model (eg update if I change a name within Tag)?

Thanks

models.py

class Tag(models.Model):
    name = models.CharField("Name", max_length=5000, blank=True)
    taglevel = models.IntegerField("Tag level", null=True, blank=True)

class Item(EsIndexable, models.Model):
    title = models.CharField("Title", max_length=10000, blank=True)
    tag = models.ManyToManyField('Tag', blank=True)

def update_search(instance, **kwargs):
    Item.es.create_index()

@receiver(m2m_changed, sender=Task.tag.through)
def index_update(instance):
    instance.es.do_index()
yarnball commented 7 years ago

I realised the answer, need to define a function on the model itself...

Hope it helps someone!

class Tag(models.Model):
    name = models.CharField(max_length=500, blank=True)
    taglevel = models.IntegerField(null=True, blank=True)

@receiver(post_save, sender= Tag)
@receiver(post_delete, sender= Tag)
def index_tag(instance, **kwargs):
    Item.objects.get().es.do_index()

def tag_index(instance, **kwargs):
    instance.es.do_index()

class Item(EsIndexable, models.Model):
    title = models.CharField(max_length=100, blank=True)
    tag = models.ManyToManyField('Tag', blank=True)

    class Elasticsearch(EsIndexable.Elasticsearch):
        serializer_class = ItemEsSerializer
        fields = ['title', 'tag']

@receiver(post_save, sender= Item)
def index_elastic(instance, **kwargs):
    instance.es.do_index()