Индексирование тегов Taggit с помощью Algolia для Django: у объекта _TaggableManager нет атрибута name

У меня возникли проблемы с использованием интеграции Algolia Django с одной из моих моделей, которая содержит TaggitManager() поле. В настоящее время я получаю следующую ошибку при запуске этой команды:

$ python manage.py algolia_reindex

AttributeError: '_TaggableManager' object has no attribute 'name'

Я взглянул на документацию Taggit, но я просто не уверен, как именно жениться на методе, описанном в методе поискового индекса Algolia.

index.py:

import django
django.setup()

from algoliasearch_django import AlgoliaIndex

class BlogPostIndex(AlgoliaIndex):
    fields = ('title')
    settings = {'searchableAttributes': ['title']}
    index_name = 'blog_post_index'

models.py:

from taggit.managers import TaggableManager

class Post(models.Model):
    ...some model fields...

    tags = TaggableManager()

3 ответа

Решение

Индексировать taggit теги с вашими полями поста, вам нужно будет предоставить вызываемый элемент, который возвращает теги поста блога в виде списка строк.

Лучший вариант - хранить их как _tags, который позволит вам фильтровать теги во время запроса.

Ваш PostIndex будет выглядеть так:

class PostIndex(AlgoliaIndex):
    fields = ('title', '_tags')
    settings = {'searchableAttributes': ['title']}
    index_name = 'Blog Posts Index'
    should_index = 'is_published'

Что касается Post:

class Post(models.Model):
    # ...some model fields...

    tags = TaggableManager()

    def _tags(self):
        return [t.name for t in self.tags.all()]

Следуя этим инструкциям, ваши записи будут проиндексированы с соответствующими тегами:

Снимок экрана с тегом Algolia explorer

Вы можете проверить taggit ветка нашего демо Django, которое демонстрирует эти шаги.

Чтобы ответить на мой собственный вопрос. Теперь я передал и модель, и модельный индекс, так что теперь Алголия знает, что индексировать, а что нет. Хотя я хотел бы, чтобы метод Algolia позволял индексировать теги taggit, увы, это, вероятно, невозможно.

Мой файл apps.py:

import algoliasearch_django as algoliasearch
from django.apps import AppConfig
from .index import PostIndex

class BlogConfig(AppConfig):
    name = 'blog'

    def ready(self):
        Post = self.get_model('Post')
        algoliasearch.register(Post, PostIndex)

Мой файл index.py:

from algoliasearch_django import AlgoliaIndex

class PostIndex(AlgoliaIndex):
    fields = ('title')
    settings = {'searchableAttributes': ['title']}
    index_name = 'Blog Posts Index'
    should_index = 'is_published'

И это должно сработать! Просто, когда вы знаете, как, или после попытки около 10 различных вариантов!

Это может вам помочь, если вы используете django==2+

Проблема в get_queryset() метод TaggableManager

Откройте с ним файл (мой путь был: Pipenv(project_name)/lib/site-packages/taggit/manager.py) Найти _TaggableManager класс и изменить имя метода get_queryset к get_query_set

Готово. Я хочу, чтобы разработчики taggit исправили это в будущих обновлениях

Так как никто не отвечает, я расскажу вам, как я решил эту проблему, но я должен сказать, что это не хороший путь и не "чистое" решение вообще. Итак, что я сделал, это зашел в "менеджеры taggit" в пакетах сайта (env->lib->python2.x/3.x-> site_packages->taggit-> Manager.py) В файле Manager.py вы будете найдите в строке 394 этот прекрасный фрагмент кода:

def __get__(self, instance, model):
            if instance is not None and instance.pk is None:
                raise ValueError("%s objects need to have a primary key value "
                                 "before you can access their tags." % model.__name__)
            manager = self.manager(
                through=self.through,
                model=model,
                instance=instance,
                prefetch_cache_name=self.name,  # this is the line I comment out when building the index,
                name=self.name  #this is the line I added and needs to be commented out after the index is build. 
            )
            return manager

Поэтому, когда я хочу перестроить поисковый индекс, я закомментирую (поместив "#" перед строкой) prefetch_cache_name=self.name, и заменить его на name=self.name, Таким образом, построение индекса будет работать. После завершения построения индекса вы должны вернуть все, как было раньше (переключите "#" на name=self.name снова и уходи prefetch_cache_name=self.name, опять видно).

Как уже упоминалось, это, вероятно, не лучший способ, но у меня была такая же боль, и это работает для меня. Это занимает одну минуту, когда у вас есть рутина. Поскольку мне приходится перестраивать индекс, может быть, раз в две недели, это не такая уж проблема для меня, но если вам приходится делать это очень часто, это может раздражать...

В любом случае, я надеюсь, что это поможет вам.

Другие вопросы по тегам