2009-07-17 9 views
2

Ich habe ein Paar von Django-Modelle mit einem Fremdschlüssel, von denen einer mit django-fts durchsuchbar ist, sagen:Reverse-Fremdschlüssel für django-fts durchsuchbare Modell in Vorlage

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

Wenn ich eine Instanz haben von Foo, in Sicht kann ich einfügen print foo.bar_set.all() und ich sehe eine Reihe von Ergebnissen. Allerdings, wenn ich versuche, es in Hinblick auf die Verwendung in einem der folgenden Wege:

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

und buchstäblich jede Konstrukt, das ich von benimmt sich denken kann, als ob foo Instanz keine bar_set Attribut hatte.

Edit: Ich bin sicher, dass ich eine Foo Instanz in der Vorlage habe ich folgende getestet wie erwartet funktionieren:

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

Ich bin sicher, dass es im Zusammenhang Bar Objekte, wie ich, dass der Check von Ansicht (print foo.bar_set.all()). Und wenn das QuerySet leer wäre, würde {{foo.bar_set.all|pprint}}[] ergeben, nicht '' (was es auf {{foo.bar_set.all|pprint}}, {{foo.bar_set|pprint}} und alle {{foo.nonexistent_attribute|pprint}} tut).

Dieses Verhalten begann, als ich die Entwicklung von SQLite-Datenbank zu PostgreSQL mit psycopg2-Treiber verschoben, um django-fts Volltextsuche zu verwenden.

Ich konnte keine andere Antwort finden, weil das googeln ist sehr schwierig: "umgekehrte Beziehung" oder "umgekehrter Fremdschlüssel" ist alles mit nicht verwandten django.core.urlresolvers.reverse Referenzen, und ich habe keine Ahnung, wie man "* _set" Ding googeln. Ein Tipp, wie man diesen googelt, wäre auch hilfreich.

Antwort

2

Dank Marcin Kaszyński 's Hilfe aus der SO konnte ich den Fehler auf django-fts BaseManager zurückverfolgen. Django-fts ist eine Volltext-Suchmaschine, die dem Manager von durchsuchbaren Klassen .search(query) Methoden hinzufügt. Ich kann Foo.objects.search("bar") schreiben. Für Bequemlichkeit, fügt es __call__ Methode an den Manager, die RelatedManager geerbt wird (Instanz davon ist die bar_set).

Der Template-Code, in django.templates.Variable._resolve_lookup Methode sieht, dass bar_set aufrufbar ist (Linie 717), wird versucht, anzurufen ohne Argumente (Linie 722), und behandelt die Variable als leer, weil Argumente benötigt wurden (Zeilen 724-726) .

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

0

{{ foo.bar_set.all }} sollte auf jeden Fall funktionieren. Bist du sicher, dass du tatsächlich eine Instanz von Foo hast?

+0

Ich habe eine Instanz von Foo ({{foo | pprint}} funktioniert, ich habe dies überprüft), und alle einfachen Attribute (wie {{foo.id}}) funktionieren. Es gibt eine Relation und es gibt verwandte Bar-Objekte, die ich durch Ausführen von print foo.bar_set.all() aus der Ansicht vor dem Rendern der Vorlage testen kann. –

+0

Hmm, seltsam. Können Sie Ihren Ansichtscode posten? –

+0

Ich fand dies, das war Interaktion mit django-fts (ich weiß, dass ich das in der ersten Version des Fragetextes nicht erwähnt habe, ich habe das nicht vermutet, um die Ursache zu sein). Siehe meine Antwort für erweiterte Erklärung. –

0

Ich empfehle, foo.bar_set.all als Wörterbuchelement in der View-Funktion zu übergeben, bevor die Seite gerendert wird, um zu sehen, ob Sie das gleiche Ergebnis erhalten.

+0

Methoden ohne Parameter werden von Template-Sprache aufgerufen (was auch mit anderen Methoden funktioniert, und wenn das Problem bei einem Methodenaufruf wäre, würde {{foo.bar_set | pprint}} * etwas *) rendern. Dies ist dokumentiert unter http://docs.djangoproject.com/en/1.0/topics/templates/#variables und in der ersten diesbezüglichen Frage beschrieben unter http://stackoverflow.com/questions/1014591/traversing-foreign- key-related-tables-in-django-templates –

+0

Du hast Recht, aber hast du meinen Vorschlag schon probiert? – AlbertoPL

+0

Ja, ich habe das bereits als Workaround verwendet, bis ich eine Lösung für das Problem finden kann (das funktioniert, da die fertige Ergebnismenge nur ein weiteres Template-Argument ist). Ich habe deine Antwort abgelehnt, weil es eine Fehlinformation war (weil ich Methoden nicht aufrufen konnte), aber ich sehe, dass du es bearbeitet hast, also nehme ich den Downvote zurück. –

Verwandte Themen