Seite 1 von 1

django newforms: Inhalt von Select ändern...

Verfasst: Mittwoch 23. Mai 2007, 16:34
von jens
Ich nutzte newforms von django und erstelle meine Form mit form_for_instance.

Das ganze sieht so aus:

Code: Alles auswählen

        PageForm = forms.models.form_for_instance(
            self.current_page, fields=(
                "content", "parent",
                "name", "shortcut", "title",
                "keywords", "description",
            ),
        )
        form = PageForm()
        html_form = form.as_p()
        html = (
            '<form action="." method="post">'
            '  <table class="form">'
            '    %s'
            '  </table>'
            '  <input type="submit" value="speichern" />'
            '</form>'
        ) % html_form
        self.response.write(html)
Ich möchte gern ein select-Feld ändern. Allerdings nur die Bezeichnungen.

Normalerweise sieht der generierte HTML Code so aus:

Code: Alles auswählen

<select id="id_parent" name="parent">
<option value="">---------</option>
<option selected="selected" value="1">Index</option>
<option value="2">ExamplePages</option>
<option value="3">Example</option>
</select>
Ich möchte gern die Texte, die der User sieht ändern. (Also in dem Fall: "Index", "ExamplePages" und "Example")

Irgendwie finde ich keinen Ansatz das umzusetzen...

Man kann bei form_for_instance auch "form" und "formfield_callback" angeben. Aber so richtig hilft mir das nicht weiter...

Interessant ist das:
http://www.djangosnippets.org/snippets/55/ Das soll aber ehr was für form_for_model sein, weil die Daten aus der DB nicht mehr vorhanden sind. Wäre irgendwie dumm, die Daten zweimal aus der DB zu holen...

Verfasst: Mittwoch 23. Mai 2007, 17:07
von apollo13
afaik, zeigt der doch __str__ an? Vielleicht gehts wenn du __str__ änderst, du brauchst es sonst eh fast nirgendwo...

Verfasst: Mittwoch 23. Mai 2007, 18:18
von Leonidas
Bei mir wird das Select-Feld in der Form-Klasse so deklariert:

Code: Alles auswählen

source = forms.ChoiceField(choices=
                [(model.id, model.name) for model in Model.objects.all()])
Als ich es programmiert habe, war es noch nicht dokumentiert, daher musste ich die Sourcen lesen und selbst überlegen wie das funktionieren soll (geht aber ganz gut, weil die Sourcen recht gut lesbar sind). Habe mir aber auch in #django etwas helfen lassen.

Verfasst: Mittwoch 23. Mai 2007, 21:14
von jens
@apollo13: Im Grunde hast du recht... Aber in meinem Fall sind das die Seitennamen im CMS. Diese "global" zu ändern, kommt nicht in frage, da sonst einige Ausgaben recht komisch aussehen ;)

@Leonidas: Das ist im Grunde der Teil, den ich mit http://www.djangosnippets.org/snippets/55/ kombinieren könnte.
Das dumme dabei ist allerdings, das IMHO zweimal die selben Daten aus der DB geholt werden. Denn mit einem form_for_instance wird die DB schon befragt, denke ich...

Ich müßte irgendwo zwischen form_for_instance und form.as_p() eingreifen und die Daten im Nachhinein ändern.
Die Frage ist, ob ich dabei überhaupt alle Daten habe, um meine Änderungen zu machen. Von daher müsste ich evtl. schon früher eingreifen.

Zur Aufklärung, was ich damit eigentlich bezwecken möchte:
Ich nutzte in PyLucid "Nested Sets" um die CMS Seiten in einem Baum anzuordnen.
Wenn der User eine Seite editiert, kann er die übergeordnete Seite (Die Vater-Seite) wählen, um diese Seite neu einzuordnen. Das ist die HTML-select-Box.
Wenn es nun viele Seiten gibt, ist es unübersichtlich einfach nur eine lange Liste zu haben. In der alten PyLucid Version habe ich diese Liste als Baum dargestellt. Dabei habe ich mit ASCII Zeiten die Seitennamen eingerückt.

Das ganze sieht dann z.B. so aus:

Code: Alles auswählen

         <option value="1">___| about</option>
         <option value="17">______| features</option>
         <option value="131">_________| unicode</option>
         <option value="153">_________| unicode test</option>
         <option value="20">______| news</option>
         <option value="57">_________| SVN news</option>
Genau das möchte ich jetzt mit django auch tun...

Der für mich einfachste weg ist es wohl, ganz auf newforms zu verzichten und die select-Box einfach selber aufzubauen... Aber das ist unschön ;)

Verfasst: Freitag 1. Juni 2007, 21:15
von jens
Noch was anderes in diesem Zusammenhang...

Ich habe gerade das inline-editing der CMS Seite in PyLucid fertig gestellt. Dazu muß ich aber zu einem kleinen unschönen "Hack" greifen. Das ganze sieht verkürzt so aus:

Code: Alles auswählen

        PageForm = forms.models.form_for_instance(self.current_page)

        html_form = PageForm()

        html_form = html_form.as_p()

        edit_page_form = html_form.replace("{", "{").replace("}", "}")
Gesammte Sourcen: http://pylucid.net/trac/browser/branche ... y?rev=1029

Ich gehe also hin und "escape" die Zeichen "{" und "}". Würde ich das nicht machen, würden django-Templates-Tags nicht in der Textarea stehen, sondern deren "Inhalt"...

In einer CMS Seite kann man halt die alten <lucidTag...> Dinge haben, die aber nun auch echte django Tags sind, wie z.b.: {% lucidTag sub_menu %}


Hat jemand eine Idee, wie man das anders machen könnte?

EDIT2: dumme idee gelöscht

Verfasst: Montag 2. Juli 2007, 17:11
von jens
jens hat geschrieben:Wenn der User eine Seite editiert, kann er die übergeordnete Seite (Die Vater-Seite) wählen, um diese Seite neu einzuordnen. Das ist die HTML-select-Box.
Wenn es nun viele Seiten gibt, ist es unübersichtlich einfach nur eine lange Liste zu haben. In der alten PyLucid Version habe ich diese Liste als Baum dargestellt.
Das geht nun mit http://pylucid.net/trac/changeset/1140 wieder ;)
Ist die Lösung über ein formfield_callback und dem zweimaligen Abfragen der Datenbank. Irgendwie doof, aber auch egal, weil es in der Praxis ja relativ selten vorkommt, das eine Seite editiert wird (Im Vergleich zu den Abfragen der Seiten).

Die Funktion kann von jedem auf pylucid.de getestet werden ;)