2010-12-14 11 views
3

Also lassen Sie uns in der letzten Minute sagen (in der Ansicht) Ich entscheide ich einen Standardwert für ein Feld angeben möchten und es versteckt machen, etwa so:Angeben des Standardwerts für das versteckte Django-Formularfeld - bone DRY?

form.fields['coconut'] = forms.ModelChoiceField(label="", widget=forms.HiddenInput(), queryset=swallow.coconuts.all(), initial=some_particular_coconut) 

Meine Frage ist: Muss ich wirklich Anführungszeichen hier angeben? Ich meine, ich weiß schon von Anfang an genau, von welcher Kokosnuss ich rede. Warum muss ich auch angeben, dass das Universum der verfügbaren Kokosnüsse die Menge der Kokosnüsse ist, die diese spezielle Schwalbe (durch die Schale) trägt?

Gibt es eine Möglichkeit, die Angabe von Queryset zu unterlassen? Einfaches Weglassen führt dazu, dass Django TypeError auslöst.

Wenn es in der Tat erforderlich ist, ist das nicht ein bisschen feucht?

Antwort

1

Das Problem ist, dass Sie versuchen, ein verstecktes ModelChoiceField einzurichten. Um eine Auswahl zu haben (Dropdown-Liste, traditionell), muss es seine Auswahlmöglichkeiten kennen - deshalb geben Sie ein Anfrage-Set an.

Aber Sie versuchen nicht, dem Benutzer eine Wahl zu geben, oder? Es ist eine versteckte Eingabe, und Sie setzen es vom Server aus (so wird es vermutlich wieder POSTED).

Mein Vorschlag ist es, einen Weg zu finden, den versteckten Eingang überhaupt zu benutzen. Ich finde sie ein bisschen hacky. Aber sonst, warum nicht einfach ein Textfeld mit some_particular_coconut.id angeben, und das ausblenden? Die einzige Verpackung des Modells ist diese ID.

+0

Ich bin in das, und ich dachte auch, dass es ein bisschen hacky war. Aber was ist die Konvention hier? Es gibt einige Fälle, in denen eine Sitzung ausreichen kann, aber nehmen wir an, dass dies nicht einer davon ist. Was dann? Was sind einige der wichtigsten Techniken? – jMyles

+0

Nun, ich bin ein Fan von Sitzungen, aber wenn Sie eine beschäftigte Webapp haben, verstehe ich, wie Sie sie vermeiden möchten. Es klingt, als ob du versuchst, ein Objekt aus dem Browser in eine andere Ansicht zu "springen" ... warum genau versuchst du das zu tun? Ich würde sagen, dass die oben genannte Technik der beste Weg ist, um diese spezielle Sache zu tun, aber es mag elegantere Wege geben, was auch immer Sie versuchen zu tun ... – Robert

0

Der Grund, warum Django ein Abfrage-Set benötigt, ist, dass, wenn Sie das Feld auf die Seite rendern, django nur die ID sendet. Wenn es zurückkommt, benötigt es Kenntnis des Abfrage-Sets, um das Objekt wieder aufzublasen. Wenn Sie das Abfrage-Set bereits zum Zeitpunkt der Formularerstellung kennen, geben Sie in Ihrer Ansicht einfach form.fields['coconut'].initial = some_particular_coconut an und lassen Sie den Rest der Definition in Ihrem forms.py?

Wenn Sie feststellen, dass Sie nur wirklich die ID senden müssen (Sie müssen nicht auf ein Objekt an Ihrem Ende aufblasen), warum nicht senden Sie es in einem Char-Feld?

+0

Aber das macht DRY noch nicht Sinn - wenn es hat eine ganze Zahl, und das Feld ist ein Fremdschlüssel, was ist der Unterschied am Ende? Mit anderen Worten, es erwartet * immer * eine Ganzzahl als Feldwert, wobei der Fremdschlüssel eine Ganzzahl PK hat. – jMyles

+0

Django weiß, dass es sich um einen ForeignKey aus dem Modell handelt. Auf der anderen Seite mache ich nur EuropeanSwallowForm (request.POST). Coconut hat einen Fremdschlüssel zum EuropeanSwallow. In der Handler-Ansicht hat Django keine Ahnung, dass ich das Feld in der Zwischenzeit jemals ausgeblendet habe. – jMyles

8

Ich denke, es ist gut, dass stackoverflow Antworten auf den "richtigen" Weg zeigen, Dinge zu tun, aber in zunehmendem Maße bleibt die ursprüngliche Frage unbeantwortet, weil der Benutzer versuchte, das Falsche zu tun. Das ist also diese Frage direkt zu beantworten, was Sie tun können:

form.fields['coconut'] = forms.ModelChoiceField(label="", widget=forms.HiddenInput(attrs={'value':some_particular_coconut}), queryset=swallow.coconuts.all()) 

Hinweis das benannte Argument zu HiddenInput bestanden, seine super hackish aber es ist eine direkte Antwort auf die ursprüngliche Frage.