Просмотр исходного кода

basic fulltext search for posts

Rafał Pitoń 8 лет назад
Родитель
Сommit
8b74b7c331

+ 0 - 1
misago/conf/defaults.py

@@ -47,7 +47,6 @@ INSTALLED_APPS = (
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
-    'django.contrib.postgres',
     'django.contrib.staticfiles',
     'django.contrib.humanize',
     'debug_toolbar',

+ 5 - 2
misago/threads/api/postendpoints/merge.py

@@ -34,12 +34,15 @@ def posts_merge_endpoint(request, thread):
         post.delete()
 
     if first_post.pk == thread.first_post_id:
-        self.post.update_search_vector(thread.title)
+        self.post.set_search_document(thread.title)
     else:
-        self.post.update_search_vector()
+        self.post.set_search_document()
 
     first_post.save()
 
+    first_post.update_search_vector()
+    first_post.save(update_fields=['search_vector'])
+
     thread.synchronize()
     thread.save()
 

+ 7 - 13
misago/threads/api/postingendpoint/reply.py

@@ -29,17 +29,18 @@ class ReplyMiddleware(PostingMiddleware):
         else:
             self.new_post(serializer.validated_data, parsing_result)
 
-        if self.mode == PostingEndpoint.EDIT:
-            if self.post.pk == self.thread.first_post_id:
-                self.post.update_search_vector(self.thread.title)
-            else:
-                self.post.update_search_vector()
+        if self.mode == PostingEndpoint.START:
+            self.post.set_search_document(self.thread.title)
+        else:
+            self.post.set_search_document()
 
         self.post.updated_on = self.datetime
         self.post.save()
 
+        self.post.update_search_vector()
         update_post_checksum(self.post)
-        self.post.update_fields.append('checksum')
+
+        self.post.update_fields += ['checksum', 'search_vector']
 
         if self.mode == PostingEndpoint.START:
             self.thread.set_first_post(self.post)
@@ -48,13 +49,6 @@ class ReplyMiddleware(PostingMiddleware):
 
         self.thread.save()
 
-        if self.mode in (PostingEndpoint.START, PostingEndpoint.REPLY):
-            if self.mode == PostingEndpoint.START:
-                self.post.update_search_vector(self.thread.title)
-            elif self.mode == PostingEndpoint.REPLY:
-                self.post.update_search_vector()
-            self.post.update_fields += ['search_document', 'search_vector']
-
         # annotate post for future middlewares
         self.post.parsing_result = parsing_result
 

+ 6 - 3
misago/threads/management/commands/rebuildpostssearch.py

@@ -32,10 +32,13 @@ class Command(BaseCommand):
         queryset = Post.objects.select_related('thread').filter(is_event=False)
         for post in batch_update(queryset):
             if post.id == post.thread.first_post_id:
-                post.update_search_vector(post.thread.title)
+                post.set_search_document(post.thread.title)
             else:
-                post.update_search_vector()
-            post.save(update_fields=['search_document', 'search_vector'])
+                post.set_search_document()
+            post.save(update_fields=['search_document'])
+
+            post.update_search_vector()
+            post.save(update_fields=['search_vector'])
 
             synchronized_count += 1
             show_progress(self, synchronized_count, posts_to_sync, start_time)

+ 2 - 1
misago/threads/models/post.py

@@ -165,12 +165,13 @@ class Post(models.Model):
     def get_absolute_url(self):
         return self.thread_type.get_post_absolute_url(self)
 
-    def update_search_vector(self, thread_title=None):
+    def set_search_document(self, thread_title=None):
         if thread_title:
             self.search_document = '\n\n'.join([thread_title, self.original])
         else:
             self.search_document = self.original
 
+    def update_search_vector(self):
         self.search_vector = SearchVector(
             'search_document',
             config=settings.MISAGO_SEARCH_CONFIG,

+ 4 - 1
misago/threads/moderation/threads.py

@@ -12,7 +12,10 @@ def change_thread_title(request, thread, new_title):
         thread.set_title(new_title)
         thread.save(update_fields=['title', 'slug'])
 
-        thread.first_post.update_search_vector(include_thread_title=True)
+        thread.first_post.set_search_document(thread.title)
+        thread.first_post.save(update_fields=['search_document'])
+
+        thread.first_post.update_search_vector()
         thread.first_post.save(update_fields=['search_vector'])
 
         record_event(request, thread, 'changed_title', {

+ 17 - 0
misago/threads/tests/test_search.py

@@ -14,6 +14,16 @@ class SearchApiTests(AuthenticatedUserTestCase):
 
         self.api_link = reverse('misago:api:search')
 
+    def index_post(self, post):
+        if post.id == post.thread.first_post_id:
+            post.set_search_document(post.thread.title)
+        else:
+            post.set_search_document()
+        post.save(update_fields=['search_document'])
+
+        post.update_search_vector()
+        post.save(update_fields=['search_vector'])
+
     def test_no_query(self):
         """api handles no search query"""
         response = self.client.get(self.api_link)
@@ -42,6 +52,7 @@ class SearchApiTests(AuthenticatedUserTestCase):
         """api handles short search query"""
         thread = testutils.post_thread(self.category)
         post = testutils.reply_thread(thread, message="Lorem ipsum dolor.")
+        self.index_post(post)
 
         response = self.client.get('%s?q=ip' % self.api_link)
         self.assertEqual(response.status_code, 200)
@@ -57,6 +68,7 @@ class SearchApiTests(AuthenticatedUserTestCase):
         """api handles query miss"""
         thread = testutils.post_thread(self.category)
         post = testutils.reply_thread(thread, message="Lorem ipsum dolor.")
+        self.index_post(post)
 
         response = self.client.get('%s?q=elit' % self.api_link)
         self.assertEqual(response.status_code, 200)
@@ -73,6 +85,7 @@ class SearchApiTests(AuthenticatedUserTestCase):
         thread = testutils.post_thread(self.category)
         post = testutils.reply_thread(
             thread, message="Lorem ipsum dolor.", is_hidden=True)
+        self.index_post(post)
 
         response = self.client.get('%s?q=ipsum' % self.api_link)
         self.assertEqual(response.status_code, 200)
@@ -89,6 +102,7 @@ class SearchApiTests(AuthenticatedUserTestCase):
         thread = testutils.post_thread(self.category)
         post = testutils.reply_thread(
             thread, message="Lorem ipsum dolor.", is_unapproved=True)
+        self.index_post(post)
 
         response = self.client.get('%s?q=ipsum' % self.api_link)
         self.assertEqual(response.status_code, 200)
@@ -104,6 +118,7 @@ class SearchApiTests(AuthenticatedUserTestCase):
         """api handles search query"""
         thread = testutils.post_thread(self.category)
         post = testutils.reply_thread(thread, message="Lorem ipsum dolor.")
+        self.index_post(post)
 
         response = self.client.get('%s?q=ipsum' % self.api_link)
         self.assertEqual(response.status_code, 200)
@@ -121,6 +136,7 @@ class SearchApiTests(AuthenticatedUserTestCase):
         """api searches threads by title"""
         thread = testutils.post_thread(self.category, title="Atmosphere of mars")
         testutils.reply_thread(thread, message="Lorem ipsum dolor.")
+        self.index_post(post)
 
         response = self.client.get('%s?q=mars atmosphere' % self.api_link)
         self.assertEqual(response.status_code, 200)
@@ -138,6 +154,7 @@ class SearchApiTests(AuthenticatedUserTestCase):
         """api handles complex query that uses fulltext search facilities"""
         thread = testutils.post_thread(self.category)
         post = testutils.reply_thread(thread, message="Atmosphere of Mars")
+        self.index_post(post)
 
         response = self.client.get('%s?q=Mars atmosphere' % self.api_link)
         self.assertEqual(response.status_code, 200)

+ 4 - 0
runtests.py

@@ -77,6 +77,10 @@ CACHES = {
 PASSWORD_HASHERS = (
     'django.contrib.auth.hashers.MD5PasswordHasher',
 )
+
+
+# Use english search config
+MISAGO_SEARCH_CONFIG = 'english'
 """
 
     if os.environ.get('TRAVIS'):