Permalink
Browse files

Use signals to update search_document full-text search fields

  • Loading branch information...
simonw committed Sep 30, 2017
1 parent 1262af9 commit c7e7b30c2de71cc0bf735611c2b149a153723fe3
Showing with 75 additions and 2 deletions.
  1. +1 −0 blog/__init__.py
  2. +10 −0 blog/apps.py
  3. +23 −2 blog/models.py
  4. +41 −0 blog/signals.py
View
@@ -0,0 +1 @@
default_app_config = 'blog.apps.BlogConfig'
View
@@ -0,0 +1,10 @@
from django.apps import AppConfig
from django.db.models import signals
class BlogConfig(AppConfig):
name = 'blog'
def ready(self):
# import signal handlers
from blog import signals
View
@@ -5,7 +5,7 @@
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.postgres.fields import JSONField
from django.contrib.postgres.search import SearchVectorField
from django.utils.html import escape
from django.utils.html import escape, strip_tags
import re
from xml.etree import ElementTree
@@ -109,6 +109,13 @@ def images(self):
et = ElementTree.fromstring('<entry>%s</entry>' % self.body)
return [i.attrib for i in et.findall('.//img')]
def index_components(self):
return {
'A': self.title,
'C': strip_tags(self.body),
'B': ' '.join(self.tags.values_list('tag', flat=True)),
}
def __unicode__(self):
return self.title
@@ -122,17 +129,31 @@ def title(self):
"""Mainly a convenence for the comments RSS feed"""
return u"A quote from %s" % escape(self.source)
def index_components(self):
return {
'A': self.quotation,
'B': ' '.join(self.tags.values_list('tag', flat=True)),
'C': self.source,
}
def __unicode__(self):
return self.quotation
class Blogmark(BaseModel):
link_url = models.URLField()
link_title = models.CharField(max_length=255)
via_url = models.URLField(blank=True, null=True, )
via_url = models.URLField(blank=True, null=True)
via_title = models.CharField(max_length=255, blank=True, null=True)
commentary = models.TextField()
def index_components(self):
return {
'A': self.link_title,
'B': ' '.join(self.tags.values_list('tag', flat=True)),
'C': self.commentary + ' ' + self.link_domain + ' ' + (self.via_title or ''),
}
def __unicode__(self):
return self.link_title
View
@@ -0,0 +1,41 @@
from django.dispatch import receiver
from django.db.models.signals import post_save, m2m_changed
from django.db.models import Value
from django.contrib.postgres.search import SearchVector
from django.db import transaction
from blog.models import BaseModel, Tag
import operator
@receiver(post_save)
def on_save(sender, **kwargs):
if not issubclass(sender, BaseModel):
return
transaction.on_commit(make_updater(kwargs['instance']))
@receiver(m2m_changed)
def on_m2m_changed(sender, **kwargs):
instance = kwargs['instance']
model = kwargs['model']
if model is Tag:
transaction.on_commit(make_updater(instance))
elif isinstance(instance, Tag):
for obj in model.objects.filter(pk__in=kwargs['pk_set']):
transaction.on_commit(make_updater(obj))
def make_updater(instance):
components = instance.index_components()
pk = instance.pk
def on_commit():
search_vectors = []
for weight, text in components.items():
search_vectors.append(
SearchVector(Value(text), weight=weight)
)
instance.__class__.objects.filter(pk=pk).update(
search_document=reduce(operator.add, search_vectors)
)
return on_commit

0 comments on commit c7e7b30

Please sign in to comment.