2009-07-17 6 views
2

J'ai une paire de modèles Django avec une clé étrangère, dont l'un est consultable avec django-FTS, dire:clé étrangère inverse pour modèle django-FTS consultable dans le modèle

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

Quand j'ai une instance de Foo, en vue je peux insérer print foo.bar_set.all() et je vois un tableau de résultats. Toutefois, si je tente de l'utiliser dans une vue, dans l'une des façons suivantes:

{{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 %} 

et littéralement toute construction que je peux penser à se comporte comme si foo instance avait pas bar_set attribut.

Edit: Je suis sûr que j'ai une instance Foo dans le modèle, je l'ai testé suivant pour fonctionner comme prévu:

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

Je suis sûr qu'il ya des objets de bar connexes, je vérifie que la vue (print foo.bar_set.all()). Et si le QuerySet était vide, {{foo.bar_set.all|pprint}} donnerait [], et non '' (ce qui est le cas pour {{foo.bar_set.all|pprint}}, {{foo.bar_set|pprint}} et {{foo.nonexistent_attribute|pprint}}).

Ce comportement a commencé lorsque j'ai déplacé le développement de la base de données SQLite vers PostgreSQL, avec le pilote psycopg2, pour utiliser la recherche de texte intégral django-fts.

Je n'ai pas trouvé d'autre réponse, car googler c'est très difficile: "reverse relation" ou "reverse foreign key" est jonché de django.core.urlresolvers.reverse références sans rapport, et je ne sais pas comment nommer "* _set" chose à Google Un indice sur la façon de google celui-ci serait utile aussi.

Répondre

2

Grâce à l'aide de Marcin Kaszyński sur le SO j'ai réussi à tracer le bug à django-fts BaseManager. Django-fts est un moteur de recherche en texte intégral, qui ajoute la méthode .search(query) au gestionnaire de classes interrogeables, je peux écrire Foo.objects.search("bar"). Pour commodité, il ajoute __call__ méthode au gestionnaire, qui est héritée par RelatedManager (instance de laquelle est le bar_set).

le code du modèle, dans la méthode django.templates.Variable._resolve_lookup, voit que bar_set est appelable (ligne 717), tente d'appeler sans argument (ligne 722), et traite la variable comme vide en raison des arguments ont été nécessaires (lignes 724-726) .

Removing the __call__ method from django-fts' BaseManager aide.

0

{{ foo.bar_set.all }} devrait certainement fonctionner. Êtes-vous sûr d'avoir une instance de Foo?

+0

J'ai une instance de Foo ({{foo | pprint}} fonctionne, j'ai vérifié cela), et tous les attributs simples (comme {{foo.id}}) fonctionnent. Il existe une relation et des objets Bar connexes, que je teste en lançant print foo.bar_set.all() à partir de la vue avant de rendre le modèle. –

+0

Hmm, impair. Pouvez-vous poster votre code d'affichage? –

+0

J'ai trouvé ceci, c'était une interaction avec django-fts (je sais que je n'ai pas mentionné cela dans la première version du texte de la question, je ne pensais pas que c'était la cause). Voir ma réponse pour une explication détaillée. –

0

Je suggère de tenter de passer foo.bar_set.all comme un élément de dictionnaire dans la fonction de vue avant de rendre la page pour voir si vous obtenez le même résultat.

+0

Les méthodes sans paramètres sont appelées par le langage template (qui fonctionne également avec d'autres méthodes, et si un problème survient avec un appel de méthode, {{foo.bar_set | pprint}} rendra * quelque chose *). Ceci est documenté à http://docs.djangoproject.com/fr/1.0/topics/templates/#variables et décrit dans la première question liée à celui-ci à http://stackoverflow.com/questions/1014591/traversing-foreign- key-related-tables-in-django-templates –

+0

Vous avez raison, mais avez-vous déjà essayé ma suggestion? – AlbertoPL

+0

Oui, je l'ai déjà utilisé comme une solution de contournement jusqu'à ce que je puisse trouver une solution au problème (cela fonctionne comme le jeu de résultats prêt est juste un autre argument de modèle). J'ai downvoted votre réponse parce que c'était une désinformation (à propos de ne pas pouvoir appeler les méthodes), mais je vous vois l'éditer, alors je reprends la downvote. –

Questions connexes