Seite 1 von 1
django newforms: forms.ModelForm
Verfasst: Donnerstag 24. Juli 2008, 16:21
von jens
django
forms.ModelForm ist ja eine schöne Sache. Ich nutzte das bei einem Model mit einem many-to-many Eintrag. Dieser wird per
MultipleChoiceField dargestellt.
Das Problem: Es wird die Anzahl der Einträge nicht limitiert. Der html code sieht so aus:
Code: Alles auswählen
...
<select multiple="multiple" name="tags" id="id_tags">
...
Dem widget könnte man theoretisch noch ein
attrs={"size": 5} mitgeben, dann wäre die größe beschränkt, rauskommen müßte dann das:
Code: Alles auswählen
...
<select multiple="multiple" name="tags" id="id_tags" size="5">
...
Das Problem ist also, wie gibt planzt man das widget attr ein, ohne in der ModelForm Klasse das ganze Feld komplett selber zu definieren?
Verfasst: Donnerstag 24. Juli 2008, 16:34
von jens
Ah... Ein Weg habe ich gefunden. Man kann im __init__ der ModelForm was basteln, siehe Zeile 18:
Code: Alles auswählen
from django import newforms as forms
from django.contrib.auth.models import User
# Paar test user erstellen
for i in xrange(1,6):
new_user = User(username="test%s" % i, email="test%s@invalid.org" % i)
new_user.save()
print User.objects.all()
print "-"*80
class UserForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
# attribute des widget ändern:
self.fields['user_permissions'].widget.attrs["size"] = 5
class Meta:
model = User
users_form = UserForm()
print "-"*80
print users_form.as_p()
Aber so richtig schön ist das nicht...
Verfasst: Freitag 25. Juli 2008, 08:09
von sma
Ohne es ausprobiert zu haben, aber ein `Field` hat eine Methode `widget_attrs()`, die man überschreiben könnte, um zusätzliche Attribute zu einem Widget hinzuzufügen. Du könntest dir damit also ein eigenes `ModelMultipleChoiceField` haben und das in deiner `ModelForm` benutzen. Willst du das nicht explizit überschreiben, kannst du in einem eigenen `ManyToManyField` die Methode `formfield()` überschreiben. Das ist aber auch nicht so ganz einfach, denn da kommt ein fertiges Exemplar zurück und man kann nicht einfach nur die Klasse ändern. Schlechtes Design. Speziell da `Field` bereits über die Choices eines `Select`-Widgets weiß...
Deine Lösung ist somit gar nicht so schlecht, denn sie gräbt nicht das halbe System um, sondern patcht das richtige Attribut kurz und schmerzlos ;)
Stefan
Verfasst: Freitag 25. Juli 2008, 12:30
von jens
Hm. Ob man über __init__ evtl. auch andere Dinge noch abändern kann? Wie z.B. einen help_text einfügen oder ein min_length?
EDIT: Habs mal publik gemacht:
http://www.djangosnippets.org/snippets/916/