Bottle Formulare

Django, Flask, Bottle, WSGI, CGI…
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

Hi
noisefloor hat geschrieben:
meego hat geschrieben: EDIT: bezieht das "Es" auf das ORM?
Gruß, noisefloor
Ja, soweit ich den WTF-Crashkurs bis jetzt verstanden habe, erzeugt man damit ja dann auch über Widget irgendwelche Felder fürs Template.
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

Was heisst das? Ist direkt aus dem WTF-Crashkurs übernommen:

Code: Alles auswählen

housetype = IntegerField('Art des Hauses', [validators.NumberRange(min=1, max=30, message=_(u'Bitte wähle ein Haus aus.'))])
NameError: name '_' is not defined
BlackJack

@meego: Das ist schon wieder so eine absolute Grundlage, die wir zudem auch schon mal hatten: Wenn man einen Namen verwendet, dann muss der vorher irgendwo definiert werden. Das ist auch beim Namen `_` nicht anders. Offenbar benutzen die das im „Crash Course“ ohne es vorher irgendwo einzuführen. Das ist konventionell ein Name unter den man `gettext.gettext()` importiert.
Benutzeravatar
noisefloor
User
Beiträge: 4181
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@meego: ein ORM is halt ein ORM und kein Formular-Framework. Genau soc wie z.B. WTForm nichts in eine Datenbank schreibt. Oder anders: für jeden Job das passende Tool.
Ja, soweit ich den WTF-Crashkurs bis jetzt verstanden habe, erzeugt man damit ja dann auch über Widget irgendwelche Felder fürs Template.
Genau. Du definierst auf dem pythonischen Weg Klasse, aus denen du später im Template die Formularfelder renderst. Der eigentliche Vorteile ist aber die Validierung und das du dich später nicht mit dem HTML und dem extrahieren der Formulardaten aus den POST-Daten rumschlagen musst.

Der Vollständigkeit halber sei noch gesagt, dass:
* es für WTForms eine Extension gibt, die das SQLAlchemy-Modellen Formulare generieren kann
* Django kann aus Modellen seinem ORM auch Formulare generieren, und zwar mit 4 kurzen Zeilen Code :-)

Gruß, noisefloor
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

BlackJack hat geschrieben:@meego: Das ist schon wieder so eine absolute Grundlage, die wir zudem auch schon mal hatten: Wenn man einen Namen verwendet, dann muss der vorher irgendwo definiert werden. Das ist auch beim Namen `_` nicht anders. Offenbar benutzen die das im „Crash Course“ ohne es vorher irgendwo einzuführen. Das ist konventionell ein Name unter den man `gettext.gettext()` importiert.
Was ist gettext? Und wie lautet der im Tutorial vermisste Import-Befehl konkret?
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

Hallo noisefloor
noisefloor hat geschrieben:.. und dem extrahieren der Formulardaten aus den POST-Daten rumschlagen musst.
Ist das nicht auch extrahieren:

Code: Alles auswählen

def register(request):
    form = RegistrationForm(request.POST)
    if request.method == 'POST' and form.validate():
        user = User()
        user.username = form.username.data
        user.email = form.email.data
        user.save()
        redirect('register')
    return render_response('register.html', form=form)
Muss man bei Bottle das Objekt request eigentlich auch so der Funktion unter der Route übergeben? Bis jetzt war das nicht nötig. Bis jetzt musste ich über request.forms.GET die Formulardaten abrufen.
* es für WTForms eine Extension gibt, die das SQLAlchemy-Modellen Formulare generieren kann
* Django kann aus Modellen seinem ORM auch Formulare generieren, und zwar mit 4 kurzen Zeilen Code :-)
Und wenn man dann nicht alle Felder der Tabelle füllt?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich glaube django wäre besser für dich, weil in der Dokumentation viele fragen schon geklärt werden...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@meego: `gettext` ist ein Modul in der Standardbibliothek. Den konkreten Import kann ich Dir nicht sagen, weil das davon abhängt wie man `gettext` verwenden will. Man kann die Funktion `gettext()` (oder eine der Variationen davon) an den Namen binden, oder man kann ein „translation“-Objekt erstellen und dessen `gettext()`-Methode (oder eine der Variationen davon) an den Namen binden, oder — und das ist bei Webanwendungen wahrscheinlich vorzuziehen — man verwendet dessen `ugettext()`-Methode (oder eine der Variationen davon). Man kann aber auch mit der `install()`-Methode eine der `*gettext()`-Methoden wirklich global installieren.

Es kann aber auch sein das man `gettext` gar nicht direkt verwenden will sondern eine weitere Bibliothek dazwischen schaltet und dessen `gettext()`-Äquivalent verwenden möchte.

Dazu muss man sich mal mit diesem ganzen Thema auseinandersetzen, und das wird Zeit beanspruchen. Sowohl was das einlesen in i18n mit Gettext & Co allgemein betrifft, also abseits von Python, denn dieses System wird ja auch bei anderen Programmiersprachen eingesetzt, als auch konkret mal mit dem entsprechenden Python-Modul(en). Und natürlich müsste man sich in die Werkzeuge einarbeiten die es zum Bearbeiten der Übersetzungen gibt. So ein paar Tage nur für dieses Thema sollte man schon einplanen.

Bei Deinem `User`-Beispiel sind das ja beides Textfelder, das wäre auch ohne WTForms nicht so viel mehr Arbeit. Aber bei anderen Feldarten käme noch die Konvertierung in den entsprechenden Datentyp, und natürlich die Validierung hinzu. Bei der E-Mail-Adresse könnte man beispielsweise prüfen ob da überhaupt etwas drin steht, und mindestens ob ein '@' enthalten ist.
Benutzeravatar
noisefloor
User
Beiträge: 4181
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Muss man bei Bottle das Objekt request eigentlich auch so der Funktion unter der Route übergeben?
Nein, das funktioniert so nicht unter Bottle. Wie in der WTForms Doku steht, sind die meisten Beispiele Pseudo-Code, der an die Syntax von Django angelehnt ist.

Am besten suchst du dir mal ein paar Webseiten die erklären, wie du die POST / Formular-Daten unter Bottle an WTForms übergibst.
Ich glaube django wäre besser für dich, weil in der Dokumentation viele fragen schon geklärt werden...
Zumal bei Django das Zusammenspiel von ORM, Templates und Formularframework klar ist - da muss man sich halt nicht wie bei Bottle + PeeWee + WTForms um's zusammenspiel kümmern. Bei ich ja wie gesagt auch eine "alte" Applikation mit Bottle + WTForms + SQLAlchemy habe - das ist auch kein Hexenwerk. Aber es ist mit Django IMHO einfacher und schneller.

Gruß, noisefloor
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

BlackJack hat geschrieben:@meego: `gettext` ist ein Modul in der Standardbibliothek. Den konkreten Import kann ich Dir nicht sagen, weil das davon abhängt wie man `gettext` verwenden will. Man kann die Funktion `gettext()` (oder eine der Variationen davon) an den Namen binden, oder man kann ein „translation“-Objekt erstellen und dessen `gettext()`-Methode (oder eine der Variationen davon) an den Namen binden, oder — und das ist bei Webanwendungen wahrscheinlich vorzuziehen — man verwendet dessen `ugettext()`-Methode (oder eine der Variationen davon). Man kann aber auch mit der `install()`-Methode eine der `*gettext()`-Methoden wirklich global installieren.


Klingt kompliziert. Ist Babel eine Konkurrenz zu gettext? Ich könnte den Unterstrich vielleicht auch erst einmal weglassen?
Benutzeravatar
noisefloor
User
Beiträge: 4181
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
meego hat geschrieben:Klingt kompliziert.
Es ist zumindest nicht trival und halt ein mehrstufiger Prozess, der von Hand durchlaufen wird.
Ist Babel eine Konkurrenz zu gettext?
Nein - Zitat aus der Doku: "As gettext provides a solid and well supported foundation for translating application messages, Babel does not reinvent the wheel, but rather reuses this infrastructure, and makes it easier to build message catalogs for Python applications." Babel vereinfacht nur bestimmte Schritte durch einen "hüschere" API.
Ich könnte den Unterstrich vielleicht auch erst einmal weglassen?
Könntest du...

Gruß, noisefloor
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

Hallo
noisefloor hat geschrieben: Am besten suchst du dir mal ein paar Webseiten die erklären, wie du die POST / Formular-Daten unter Bottle an WTForms übergibst.
Die sind leider nicht vorhanden (bzw. ich hab' konkret nur Deinen Blogeintrag zu einem Bildupload gefunden).
Am ehesten noch eine von Flask: http://flask.pocoo.org/docs/0.10/patter ... #the-forms
Bei ich ja wie gesagt auch eine "alte" Applikation mit Bottle + WTForms + SQLAlchemy habe - das ist auch kein Hexenwerk. Aber es ist mit Django IMHO einfacher und schneller.
Noch einmal von vorne beginnen? Was bei Django wenig klar war, war wieso man eine "my_site" erstellen muss, um dann in einem unterordner noch einmal eine "app" mit demselben namen zu erstellen. Oft sah man leider auch nicht wirklich dahinter, was Django genau macht, während ich beim jetzigen Code den Überblick doch noch ziemlich genau habe. Und die Routen werden (völlig unnötig) über Regex definiert (sicherlich auch wieder ein riesen Thema für sich).
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

meego hat geschrieben:
Übersetzung: Wenn du Django benutzen würdest, wie seit Wochen empfohlen, müsstest du auch das Rad "Verwaltung übersetzter Texte" nicht neu erfinden.
Will ich auch nicht. Und dafür müsste ich dann vermutlich erst einmal ein halbes Jahr lang das wesentlich unintuitivere Django erlernen, um überhaupt etwas damit anstellen zu können.
Python und Django lernen, damit eine Webanwendung schreiben und deployen kann man an einem Tag machen, passiert z.B. bei Django Girls. Da geht es natürlich nur um die absoluten Grundlagen, darauf muss man natürlich aufbauen. Ob mit oder ohne Django wirst du allerdings mehr als ein halbes Jahr, wahrscheinlich sogar mehr als ein Jahr brauchen, um gute professionelle Webanwendungen entwickeln zu können. Allein Internationalisierung ist ein Thema mit dem man sich tagelang beschäftigen kann ohne alle Details verstanden zu haben.

Ich würde dir empfehlen mal eine Pause zu machen und mal kritisch zu betrachten was du gerade tust, es ist nämlich vollkommener Schwachsinn. Du kannst noch nichtmal Python, kennst nicht die Grundlagen von Webentwicklung und versuchst als erste Webanwendung etwas zu entwickeln, dass weitab davon ist als Einstiegsprojekt zu taugen und eher im Bereich dessen ist womit sich sonst ein Team von Profis beschäftigen würde.
Benutzeravatar
noisefloor
User
Beiträge: 4181
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Was bei Django wenig klar war, war wieso man eine "my_site" erstellen muss, um dann in einem unterordner noch einmal eine "app" mit demselben namen zu erstellen
Die App kann jeden Namen haben - die muss nicht wie das Projekt heißen. Das Projekt ist halt dazu da, um bestimmte Sachen wie z.B. Benutzerverwaltung an einer Stelle zu bündeln.
Oft sah man leider auch nicht wirklich dahinter, was Django genau macht,
Also ohne dir zu nah treten zu wollen - du weißt jetzt auch nicht, was Bottle, PeeWee und WTForms machen. Und eigentlich ist das auch egal, weil erst Mal wichtig ist, die API zu verstehen. Bei Django ist die API an vielen Stellen ziemlich high-level, was heißt: du erreichst mit wenig Code ziemlich viel. Was für Django spricht. Bei Bedarf könntest du aber auch in die Untiefen der Low-Level API abtauchen (die Django Doku hat nicht umsonst gerdruckt > 1500 Seiten). Willst du aber gar nicht.

Aber solange du deine Vorurteile gegen Django pflegst und eine Teil der gut gemeinten Ratschläge ignorierst ist es halt so, wie DasIch sagt...

Gruß, noisefloor
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

Hallo

Naja, ich habe schon eine ziemlich gute Idee davon, wie der Programmfluss jetzt ausschaut.

Und das Eure Meinung inbesondere für Newbies (ich kann Python auf dem Level vom Rice Kurs) z.B. überhaupt nicht mit Quora konsistent geht, habe ich ja auch schon einmal erwähnt:
http://www.quora.com/Should-I-learn-Flask-or-Django
Benutzeravatar
noisefloor
User
Beiträge: 4181
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
meego hat geschrieben:Naja, ich habe schon eine ziemlich gute Idee davon, wie der Programmfluss jetzt ausschaut.
Axo - darum geht's. Klang oben anders ;-)

Der vollständigkeit halber sei noch erwähnt das:
* bei Django der sogenannten Programmfluss in der Datei `views.py` definiert ist
* es kein Geheimnis ist, das DasIch aktiv bei Flask mit entwickelt

Gruß, noisefloor
BlackJack

@meego: Du hast auch schon SO-Fragen velinkt wo `dict.update()` mit *einem* Schlüssel/Wert-Paar als gute Idee hingestellt wurde. ;-)

Habe jetzt mal über die Quora-Antworten drübergelesen und das sieht so aus als wenn die die Flask bevorzugen, das tun weil es so schön klein und übersichtlich ist — weil vieles von dem was Django bietet halt gar nicht direkt dabei ist. Aber genau an diesem nachinstallieren und dem Zusammenspiel der anderen Komponenten wie ORM und Form-Bibliothek beginnen doch Deine Probleme. Das sind bei Django Sachen die schon dabei sind, die zusammenarbeiten, die zusammen dokumentiert sind.

Andererseits habe ich bei Dir das Gefühl das ein grosses Problem ist, dass Du die Sprache und wie sie funktioniert noch nicht so ganz verstehst und keine API-Dokumentation liest *und verstehst*, Dir folglich alles aus irgendwelchen Beispielen zusammenstöpselst, und Dich dann über Fehler wunderst die eigentlich offensichtlich sein müssten.
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

Hallo

SO ist schlecht? Naja, es hatte auch einige Newbies darunter, die es bevorzugen. Aber evtl. schaue ich mir das Djangogirls dann noch einmal an. Beim letzten Mal bin ich beim etwas unpässlichen Git-Beschrieb stecken geblieben.

Bei der WTF Implementation im Bottletemplate erhalte ich diesen Traceback:
u' <div class="form-group">', _str(form.optionen.label), u': ', _str(form.optionen(class="css_class")), u'</div>\n'\

Aufgrund:

<div>{{!form.optionen.label}}: {{!form.optionen(class="css_class")}}</div>

Und es hat mit der Übergabe der CSS-Klasse zu tun. Das '!' ist Bottle-eigen.

WTForms Doku:

Code: Alles auswählen

<form method="POST" action="/login">
    <div>{{ form.username.label }}: {{ form.username(class="css_class") }}</div>
    <div>{{ form.password.label }}: {{ form.password() }}</div>
</form>
BlackJack

@meego: SO ist nicht generell schlecht, aber natürlich ist dort auch nicht alles Gold. Getreu dem Motto „Früher war alles besser“ habe ich das Gefühl es werden, zumindest beim Thema Python, momentan zu viele Fragen gestellt, so dass vieles unbeantwortet oder suboptimal beantwortet vorbei rauscht.

Diese eine Zeile ist kein Traceback. Aber ich vermute mal das ``class`` ist das Problem, denn wenn man das mal mit Syntaxhervorhebung anschaut, sieht man dass das Schlüssselwort dort als Python-Code interpretiert wird und in Python kann man keine Namen oder Argumente nach Schlüsselworten benennen:

Code: Alles auswählen

u' <div class="form-group">', _str(form.optionen.label), u': ', _str(form.optionen(class="css_class")), u'</div>\n'
Das Problem liegt an der Stelle an dem relativ einfach gestrickten Bottle-eigenen Templatesystem, während die WTF-Dokumentation von etwas ähnlichem wie Django-Templating oder beispielsweise Jinja2 ausgeht. Letzteres benutze ich mit Bottle und da funktioniert so ein Argument.
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

Hallo Blackjack
BlackJack hat geschrieben:Diese eine Zeile ist kein Traceback.
Hier wär's noch komplett:

Code: Alles auswählen

Traceback (most recent call last):
  File "/home/nuc/Dropbox/x/views/x.tpl", line 76
    u'    <div class="form-group">', _str(form.optionen.label), u': ', _str(form.optionen(class="css_class")), u'</div>\n'\
                                                                                                    ^
SyntaxError: invalid syntax
Das Problem liegt an der Stelle an dem relativ einfach gestrickten Bottle-eigenen Templatesystem, während die WTF-Dokumentation von etwas ähnlichem wie Django-Templating oder beispielsweise Jinja2 ausgeht. Letzteres benutze ich mit Bottle und da funktioniert so ein Argument.
Das ist natürlich schade, wenn sich Bottle da nicht an die Standards hält. Meinst du die Simple Template Engine lässt gar keine CSS Argumente zu?

Edit: Mit class_= geht's.
Antworten