Seite 1 von 1

Django: Feld-Labels sind nicht DRY

Verfasst: Samstag 11. Juli 2009, 09:31
von filchos
Hallo,

man nehme ein Feld für einen Vornamen:

models.py:

Code: Alles auswählen

firstname = models.CharField(max_length = 50, blank=True, verbose_name='Vorname')
forms.py:

Code: Alles auswählen

firstname = forms.CharField(max_length = 50, required=True, label='Vorname')
Das Admininterface holt sich verbose_name aus models.py.
Die Templates der Webanwendung holen sich label aus forms.py.

Also muss ich sämtliche Feldbezeichnungen doppelt schreiben. Gibt es eine Möglichkeit, dies zu verhindern?

Grüße,
Olaf

P.S.: Das Weglassen des Formelements ist keine Lösung, da ich hier (nicht im obrigen Beispielcode vorhanden) eigene Widgets und auch eigene Field-Klassen benutze.

Re: Django: Feld-Labels sind nicht DRY

Verfasst: Samstag 11. Juli 2009, 09:56
von Leonidas
filchos hat geschrieben:Also muss ich sämtliche Feldbezeichnungen doppelt schreiben. Gibt es eine Möglichkeit, dies zu verhindern?
Form-Klasse aus Model-Klasse erstellen lassen?

Re: Django: Feld-Labels sind nicht DRY

Verfasst: Samstag 11. Juli 2009, 12:12
von apollo13
filchos hat geschrieben:

Code: Alles auswählen

firstname = models.CharField(max_length = 50, blank=True, verbose_name='Vorname')
Abgesehen von dem was Leonidas sagte, wird die obere Zeile üblicherweise so geschrieben:

Code: Alles auswählen

firstname = models.CharField('Vorname', max_length = 50, blank=True)
Nur bei ForeignKey Fields musst du explizit verbose_name verwenden…

Re: Django: Feld-Labels sind nicht DRY

Verfasst: Samstag 11. Juli 2009, 18:46
von filchos
Leonidas hat geschrieben:Form-Klasse aus Model-Klasse erstellen lassen?
Hm,

die Klassendefinition des Models ist:

Code: Alles auswählen

class User(models.Model):
    # […]
Die des zugehörigen Formobjekts:

Code: Alles auswählen

class UserForm(forms.ModelForm):
    # […]
    class Meta:
        model = User
was muss ich zusätzlich tun, um die Form-Klasse aus der Model-Klasse erstellen zu lassen?

Grüße,
Olaf

Re: Django: Feld-Labels sind nicht DRY

Verfasst: Samstag 11. Juli 2009, 18:55
von Leonidas
filchos hat geschrieben:was muss ich zusätzlich tun, um die Form-Klasse aus der Model-Klasse erstellen zu lassen?
Steht doch in der Dokumentation :?:

Verfasst: Samstag 11. Juli 2009, 19:20
von filchos
Hallo Leonidas,

anhand dieser Dokumentation habe ich auch gearbeitet. Einziger Unterschied ist die Art, wie ich im View eine Instanz erzeuge:

Code: Alles auswählen

def edit(request):
    # […]
    # user is a single User object
    params = {'instance': user}

    if request.method == 'POST':
        form = UserForm(request.POST, **params)
    else:
        form = UserForm(**params)

Verfasst: Samstag 11. Juli 2009, 19:29
von Leonidas
Und wo ist jetzt das Problem? Jetzt kannst du in deiner Form-Klasse die Felder weglassen und bist fertig; DRY wiederhergestellt.

Verfasst: Samstag 11. Juli 2009, 21:13
von filchos
Ich habe jetzt in der Form-Klasse Felddefinitionen aus zwei Gründen:

(a) ich benutze ein bestimmtes Widget:

Code: Alles auswählen

dateofbirth = forms.DateField(widget = GermanDateWidget, label='Geburtsdatum')
(b) ich habe ein eigenes Feld, welches von RegexField erbt, aber eine feste RegEx vorgibt, da in vielen Feldern nur bestimmte Zeichen erlaubt sein sollen.

Code: Alles auswählen

firstname = SecureLineField(max_length = 50, required=True, label='Vorname')
Deswegen kommt ein reines Weglassen nicht in Frage. Es sei denn, ich kann diese Informationen auch in das Model schieben (wo die Widgets aber schon logisch nicht hingehören).

Verfasst: Samstag 11. Juli 2009, 21:29
von Leonidas
Wo sich mir die Frage stellt, warum du das nicht von Anfang an gesagt hast...

Letztendlich musst du halt nur die Formfelder definieren wo du von den Standardwerten abweichst, fürs auswechseln der Widgets gibs im Abschnitt "Overriding the default field types" ein Beispiel.

Verfasst: Samstag 11. Juli 2009, 21:38
von apollo13
Um es dann allerdings DRY zu halten würde ich das ganze in dem __init__ des Modelforms patchen, da sonst der helptext und das Label wieder verloren gehen (für die Felder die du überschreibst).

Verfasst: Samstag 11. Juli 2009, 21:39
von filchos
Hallo Leonidas,
Leonidas hat geschrieben:Wo sich mir die Frage stellt, warum du das nicht von Anfang an gesagt hast...
Das habe ich ein bisschen im P.S. meines Ausgangspostings versteckt …

Letztendlich verfahre ich auch so, wie unter „Overriding the default field types“ beschrieben. Mich wundert bloß, dass dann in der Form-Felddefinition nicht automatisch verbose_name der Modell-Felddefinition verwendet wird, sondern ich explizit label angeben muss.

Grüße,
Olaf

Verfasst: Sonntag 12. Juli 2009, 12:24
von apollo13
filchos hat geschrieben: Letztendlich verfahre ich auch so, wie unter „Overriding the default field types“ beschrieben. Mich wundert bloß, dass dann in der Form-Felddefinition nicht automatisch verbose_name der Modell-Felddefinition verwendet wird, sondern ich explizit label angeben muss.
Das ist nicht verwunderlich sondern logisch, wie soll das auch gehen? Du bietest dein eigenes FormField an, natürlich wird dann dessen label verwendet… Was anderes zu erwarten würde mehr als gegen den „Zen of Python“ sein; es wäre implizit und magisch…

Verfasst: Montag 13. Juli 2009, 07:05
von filchos
Hallo apollo13,
apollo13 hat geschrieben:Um es dann allerdings DRY zu halten würde ich das ganze in dem __init__ des Modelforms patchen […]
hast Du ein kurzes Codebeispiel für mich oder ein Tipp, wo dokumentiert ist, wie ich in __init__ die Felder ändern kann, anstatt sie neu zu setzen?

Grüße,
Olaf

Verfasst: Montag 13. Juli 2009, 08:22
von apollo13
Das ist zwar nimmer 100% aktuell, aber beschreibt es recht gut denk ich: http://wadofstuff.blogspot.com/2009/02/ ... s-and.html

Verfasst: Montag 13. Juli 2009, 08:29
von jens

Verfasst: Dienstag 14. Juli 2009, 06:50
von filchos
Hallo jens, hallo apollo13,

vielen Dank für die die interessanten Links. Die nächsten Tage ist noch anderes dran, dann werde ich mich der Sache wieder widmen.

Danke und Grüße,
Olaf