kopia lustrzana https://github.com/wagtail/wagtail
Prevents PostgreSQL from duplicating ancestor and descendant entries of a same instance.
rodzic
50a52c20a6
commit
7238125e4b
|
@ -15,8 +15,9 @@ from wagtail.wagtailsearch.index import RelatedFields, SearchField
|
|||
|
||||
from .models import IndexEntry
|
||||
from .utils import (
|
||||
ADD, AND, OR, WEIGHTS_VALUES, get_content_types_pk, get_descendants_content_types_pks,
|
||||
get_postgresql_connections, get_weight, keyword_split, unidecode)
|
||||
ADD, AND, OR, WEIGHTS_VALUES, get_ancestors_content_types_pks, get_content_type_pk,
|
||||
get_descendants_content_types_pks, get_postgresql_connections, get_weight, keyword_split,
|
||||
unidecode)
|
||||
|
||||
|
||||
# TODO: Add autocomplete.
|
||||
|
@ -33,6 +34,7 @@ class Index(object):
|
|||
'You must select a PostgreSQL database '
|
||||
'to use PostgreSQL search.')
|
||||
self.db_alias = db_alias
|
||||
self.index_entries = IndexEntry._default_manager.using(self.db_alias)
|
||||
self.name = model._meta.label
|
||||
self.search_fields = self.model.get_search_fields()
|
||||
|
||||
|
@ -52,8 +54,7 @@ class Index(object):
|
|||
.values('object_id'))
|
||||
content_type_ids = get_descendants_content_types_pks(self.model)
|
||||
stale_entries = (
|
||||
IndexEntry._default_manager.using(self.db_alias)
|
||||
.filter(content_type_id__in=content_type_ids)
|
||||
self.index_entries.filter(content_type_id__in=content_type_ids)
|
||||
.exclude(object_id__in=existing_pks))
|
||||
stale_entries.delete()
|
||||
|
||||
|
@ -123,8 +124,7 @@ class Index(object):
|
|||
for text, weight in obj._body_])
|
||||
if obj._body_ else SearchVector(Value('')))
|
||||
ids_and_objs[obj._object_id] = obj
|
||||
index_entries = IndexEntry._default_manager.using(self.db_alias)
|
||||
index_entries_for_ct = index_entries.filter(
|
||||
index_entries_for_ct = self.index_entries.filter(
|
||||
content_type_id=content_type_pk)
|
||||
indexed_ids = frozenset(
|
||||
index_entries_for_ct.filter(object_id__in=ids_and_objs)
|
||||
|
@ -141,14 +141,21 @@ class Index(object):
|
|||
object_id=object_id,
|
||||
body_search=ids_and_objs[object_id]._search_vector,
|
||||
))
|
||||
index_entries.bulk_create(to_be_created)
|
||||
self.index_entries.bulk_create(to_be_created)
|
||||
|
||||
def add_items(self, model, objs):
|
||||
content_type_pk = get_content_types_pk(model)
|
||||
content_type_pk = get_content_type_pk(model)
|
||||
config = self.backend.get_config()
|
||||
for obj in objs:
|
||||
obj._object_id = force_text(obj.pk)
|
||||
obj._body_ = self.prepare_body(obj)
|
||||
|
||||
# Removes index entries of an ancestor model in case the descendant
|
||||
# model instance was created since.
|
||||
self.index_entries.filter(
|
||||
content_type_id__in=get_ancestors_content_types_pks(model)
|
||||
).filter(object_id__in=[obj._object_id for obj in objs]).delete()
|
||||
|
||||
connection = connections[self.db_alias]
|
||||
if connection.pg_version >= 90500: # PostgreSQL >= 9.5
|
||||
self.add_items_upsert(connection, content_type_pk, objs, config)
|
||||
|
|
|
@ -60,19 +60,31 @@ def get_descendant_models(model):
|
|||
return descendant_models
|
||||
|
||||
|
||||
def get_content_type_pk(model):
|
||||
# We import it locally because this file is loaded before apps are ready.
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
return ContentType.objects.get_for_model(model).pk
|
||||
|
||||
|
||||
def get_ancestors_content_types_pks(model):
|
||||
"""
|
||||
Returns content types ids for the descendants of this model, excluding it.
|
||||
"""
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
return [ct.pk for ct in
|
||||
ContentType.objects.get_for_models(*model._meta.parents).values()]
|
||||
|
||||
|
||||
def get_descendants_content_types_pks(model):
|
||||
"""
|
||||
Returns content types ids for the descendants of this model, including it.
|
||||
"""
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
return [ct.pk for ct in
|
||||
ContentType.objects.get_for_models(*get_descendant_models(model))
|
||||
.values()]
|
||||
|
||||
|
||||
def get_content_types_pk(model):
|
||||
# We import it locally because this file is loaded before apps are ready.
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
return ContentType.objects.get_for_model(model).pk
|
||||
|
||||
|
||||
def get_search_fields(search_fields):
|
||||
for search_field in search_fields:
|
||||
if isinstance(search_field, SearchField):
|
||||
|
|
Ładowanie…
Reference in New Issue