Обратный внешний ключ к поисковой модели django-fts в шаблоне - PullRequest
2 голосов
/ 17 июля 2009

У меня есть пара моделей Django с внешним ключом, одна из которых доступна для поиска с помощью django-fts, скажем:

class Foo(models.Model):
    ...
class Bar(fts.SearchableModel):
    foo = models.ForeignKey(Foo)

Когда у меня есть экземпляр Foo, я могу вставить print foo.bar_set.all() и увидеть массив результатов. Однако, если я попытаюсь использовать его в представлении, любым из следующих способов:

{{foo.bar_set|pprint}}
{{foo.bar_set.all|ppring}}
{{foo.bar_set.count}}
{{foo.bar_set.all|length}}
{% for bar in foo.bar_set.all %} {{bar}} {% endfor %}

и буквально любая конструкция , о которой я могу думать, ведет себя так, как будто экземпляр foo не имеет атрибута bar_set.

Edit: я уверен, что у меня есть Foo экземпляр в шаблоне, я протестировал следующее, чтобы работать как ожидалось:

{{foo|pprint}}
{{foo.id}} (and any other simple attributes of Foo)

Я уверен, что есть связанные объекты Bar, поскольку я проверяю это из вида (print foo.bar_set.all()). И если бы QuerySet был пуст, {{foo.bar_set.all|pprint}} дал бы [], а не '' (что он делает на {{foo.bar_set.all|pprint}}, {{foo.bar_set|pprint}} и любых {{foo.nonexistent_attribute|pprint}}).

Такое поведение началось, когда я переместил разработку из базы данных SQLite в PostgreSQL с драйвером psycopg2 для использования полнотекстового поиска django-fts.

Я не смог найти никакого другого ответа, потому что поискать в Google это очень сложно: «обратная связь» или «обратный внешний ключ» полны несвязанных django.core.urlresolvers.reverse ссылок, и я понятия не имею, как назвать «* _set» вещь для Google. Подсказка о том, как это Google, также будет полезна.

Ответы [ 3 ]

2 голосов
/ 17 июля 2009

Благодаря помощи Marcin Kaszyński от SO Мне удалось отследить ошибку до django-fts BaseManager. Django-fts - это механизм полнотекстового поиска, который добавляет метод .search(query) в менеджер классов с возможностью поиска, так что я могу написать Foo.objects.search("bar"). Для удобства в диспетчер добавлен метод __call__, который наследуется RelatedManager (экземпляром которого является bar_set).

Код шаблона в методе <a href="http://code.djangoproject.com/browser/django/trunk/django/template/__init__.py?rev=10519#L701" rel="nofollow noreferrer">django.templates.Variable._resolve_lookup</a> видит, что bar_set может вызываться (строка 717), пытается вызвать его без аргументов (строка 722) и обрабатывает переменную как пустую, потому что требуются аргументы (строки 724 -726).

Удаление метода __call__ из BaseManager django-fts помогает.

0 голосов
/ 17 июля 2009

Я предлагаю попытаться передать foo.bar_set.all как элемент словаря в функции представления перед рендерингом страницы, чтобы увидеть, если вы получите тот же результат.

0 голосов
/ 17 июля 2009

{{ foo.bar_set.all }} определенно должно работать. Вы уверены, что у вас есть экземпляр Foo?

...