Bottle, HTML Datenbankzugriff

Django, Flask, Bottle, WSGI, CGI…
DanJJo
User
Beiträge: 90
Registriert: Mittwoch 13. Februar 2013, 18:35

Hallo an euch,

Ich bin gerade dabei eine seite zu basteln und bräuchte hierfür einen Login bereich. Mit sqlite ab ich eine DB aufgesetzt und auch schon einen User importiert. Nun ist meine Frage, wie ich die Abfrage mit der DB verknüpfe. Hierzu erstmal mein HTML bzw. mein bottle.tpl Code:

Code: Alles auswählen

...					<form method="POST" action="/login_submit">
						<p>username</p>
						<input name="name" type="text" size="30" maxlength="50" /> 
						<p>passwort</p>
						<input name="password" type="password" size="30" maxlength="50"/> 
						<p></p>
						<input type="submit" />
					        </form>...
und die py:

Code: Alles auswählen

@route('/login', method='POST')
def login_submit(db):
    name     = request.forms.get('name')
    password = request.forms.get('password')
    sql=db.execute("SELECT UserName, Password FROM User where UserName = name and Password = password")
    row=sql.fetchone();
    if (name==row):
        return template("login_submit")
    else:
        return "<p>Login failed</p>"
ich weiß, dass die py nicht korrekt ist aber ich bekomm es einfach nicht zusammen. Wäre nett wenn mir jmd weiter helfen könnte.

Danke

Grüße

...
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

Hi,

versuch mal anstelle von:

Code: Alles auswählen

<form method="POST" action="/login_submit">
das:

Code: Alles auswählen

<form method="POST" action="/login">
Ich denke mal du musst die Route aufrufen und nicht die Funktion.

Die funktion login_submit mal ohne (db) aufrufen.

Code: Alles auswählen

def login_submit():
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo Danjjo,

sieht so aus, als ob Du das bottle-sqlite-plugin benutzt, richtig?

friedduck hat schon richtig angemerkt, dass die url /login heißen muß.
Dann solltest Du Dir unbedingt ein Tutorial über sqlite im Speziellen und SQL im Allgemeinen
durcharbeiten. Für eine richtige User-Session-Verwaltung brauchst Du außerdem noch
cookies (siehe bottle-Docu), damit Du später auch noch weißt, wer eingeloggt ist. Dann sollten Passwörter
wirklich nie im Klartext irgendwo gespeichert sein, sondern nur ein ordentlich
gesalzener Cryptograpischer Hashwert (z.B: PBKDF2).
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

hier ist ein gutes tut zu sqlite (Python): http://www.doughellmann.com/PyMOTW/sqlite3/index.html
DanJJo
User
Beiträge: 90
Registriert: Mittwoch 13. Februar 2013, 18:35

Also habs gelöst! Danke euch...

hab aber eine weitere Frage. Wenn ich mir eine info über die Homepage ziehe kann ich diese info in der Datenbank verwenden?

bsp:

Code: Alles auswählen

searching = request.forms.get('search')
	sql1=db.execute('SELECT Formel1Wagen FROM Wagen where searching==Formel1Wagen')
sprich in searching steht z.b Ferrari....bei der jetzigen benutzung vergleicht er das Wort "searching" mit den Formel1Wagen und nicht Ferrari. Wie bekomm ich es hin, dass er an das Ferrari ran kommt?!

Danle
BlackJack

@DanJJo: friedduck hat doch einen Link zu einem Tutorial gepostet: http://www.doughellmann.com/PyMOTW/sqlite3/index.html

Einfach mal durcharbeiten. :-)
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

DanJJo hat geschrieben:Also habs gelöst! Danke euch...
Es wäre fair wenn du deinen Lösungseinsatz hier posten würdest, für die anderen, die sich vll. mit dem selben Problem herumschlagen.
DanJJo hat geschrieben: hab aber eine weitere Frage. Wenn ich mir eine info über die Homepage ziehe kann ich diese info in der Datenbank verwenden?

bsp:

Code: Alles auswählen

searching = request.forms.get('search')
	db.execute('SELECT Formel1Wagen FROM Wagen where searching==Formel1Wagen')
sprich in searching steht z.b Ferrari....bei der jetzigen benutzung vergleicht er das Wort "searching" mit den Formel1Wagen und nicht Ferrari. Wie bekomm ich es hin, dass er an das Ferrari ran kommt?!

Danle
Wir wissen leider nicht wie deine Datenbank aufgebaut ist...
Angenommen, du hast Tabelle "Wagen" mit den Spalten "id" und "name", wobei die id selbständig hochgezählt wird (autoincrement) und in der Spalte "name" stehen die Namem der Fahrzeuge, also Ferrari u.s.w.

Dann würde der SQL aufruf lauten:

Code: Alles auswählen

SELECT name FROM Wagen WHERE name = "Ferarri"
In Python würde man es so schreiben:

Code: Alles auswählen

db.execute( 'SELECT name FROM Wagen WHERE name = ?' ('Ferarri',) )
Das unscheinbare kommazeichen hinter Ferrari ist wichtig, sonst wird es nix mit der Abfrage.

Ansonsten kann ich dir das SQLite Manager Plugin für Firefox sehr Empfehlen. Dort kannst du ohne Stress eine Datenbank im Speicher erstellen und nach Herzenslust mit den Abfragen rumspielen.
DanJJo
User
Beiträge: 90
Registriert: Mittwoch 13. Februar 2013, 18:35

Also momentaner stand...ist noch nicht fertig aber es geht in die richtige Richtung...natürlich noch keine verschlüsselung des pw etc...

also in der *.py

Code: Alles auswählen

@route('/login_submit', method='POST')
def login_submit(db):
    name     = request.forms.get('name')
    password = request.forms.get('password')
    sql=db.execute('SELECT UserName FROM User')
    row=sql.fetchone()
    if name in row:
	response.set_cookie("account", name, secret='keykey')
        return "<p>Login ok</p>"
    else:
        return "<p>Login failed</p>"
im *.tpl

Code: Alles auswählen

 <form method="POST" action="/login_submit">
nun zu meiner zweiten Frage...

friedduck: Das versteh ich und kenn es auch aber meine Frage ist, wie ich eine Angabe, die von der Homepage kommt, also die z.B in der Variablen "searching" steht in der DB abfrage...

also ich geh auf die Homepage und geben ein "Ferrari" -> Ferrari wird in die Var. "searching" geladen. DB abfrage funktioniert nicht wenn ich sage ("Select Formel1Wagen From Wagen Where Name == searching")
....logisch, da er natürlich nach Wagen mit den Namen Searching sucht und nicht nach Ferrari ;)


vllt jetzt etwas verständlicher....

EDIT:OK Das tut brachte die Antwort. Danke :)

Code: Alles auswählen

searching = request.forms.get('search')
	sql1=db.execute('SELECT Formel1Wagen FROM Wagen where Name=?',(searching,))

und ja ich bin dabei mir das tut an zu schauen :)
DanJJo
User
Beiträge: 90
Registriert: Mittwoch 13. Februar 2013, 18:35

Hab da mal wieder eine Frage , die ich mir bislang nicht beantworten kann...

Wenn ich eine Route Hab und mehrere Fkt. werden bei dieser Route alle Fkt abgearbeitet? kann ich vllt durch irgendwelche "ID" bestimmen welche abgearbeitet werden sollen? Danke

Bsp:

Code: Alles auswählen

@route("/bla", method='POST')
@route("/bla/", method='POST')

def bla1 (db):
....
def bla2(db):
danke :)
BlackJack

@DanJJo: Ich verstehe die Frage und vor allem auch das Quelltextbeispiel nicht. Die Dekoratorsyntax bezieht sich auf das Konstrukt was ihr folgt, also Funktions- oder Klassendefinition. Beide Dekoratoren beziehen sich demnach auf `bla1()`. Vielleicht solltest Du mal nachlesen was die Dekoratorsyntax ist und wie man das ohne umschreiben würde. Also wie man das gemacht hat bevor eine eigene Syntax dafür eingeführt wurde.
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

Hmm, wie wäre es mit:

Code: Alles auswählen

@route("/bla/<name>", method='POST')
DanJJo
User
Beiträge: 90
Registriert: Mittwoch 13. Februar 2013, 18:35

Ok Danke.

nächste Frage.

wenn ich mir etw. aus der Datenbank hole mit

Code: Alles auswählen

sql = db.execute('SELECT bla FROM blabla ORDER BY blub ASC')
row=sql.fetchone()
nun steht in row meine Info in dem format....

(u 'bla',)

komm ich irgendwie einfach nur an das "bla" ohne die utf geschichte drum?
BlackJack

@DanJJo: Mit der `type()`-Funktion kannst Du heraus bekommen welchen Typ das Objekt hat — obwohl man das eigentlich erkennen sollte, wenn man das Python-Tutorial in der Python-Dokumentation durchgearbeitet hat — und in der Python-Dokumentation kannst Du dann nachlesen welche Operationen es auf Werten von diesem Typ gibt.
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

@ BlackJack:
Mit der `type()`-Funktion kannst Du heraus bekommen welchen Typ das Objekt hat
Es gibts ja noch die funktion / methode __class__ , also row.__class__ die genau das gleiche ausgeben würde, oder? Wann ist es eigentlich Sinnig methoden zu verwenden, anstelle von funktionen? Oder ist es auch geschmackssache?

Ein Beispiel:
liste = [1,2,3,4,5]
len(liste)
liste.__len__()
BlackJack

@friedduck: Die Unterstrich-Methoden sollte man nur benutzen wenn es keinen anderen Zugriff gibt. Also nicht `__len__()` aufrufen wenn man `len()` verwenden kann. Ein `__class__`-Attribut muss es nicht zwingend geben, wenn es kein „echtes” ``class``-Objekt gibt. Bei Typen die man in C-Erweiterungen implementiert könnte das zum Beispiel passieren, zumindest bei Python 2.x. Denn dort gab es früher mal einen Unterschied zwischen Typen und Klassen, heisst nicht jeder Datentyp brauchte eine dazugehörige Klasse.

Dann gibt es noch Funktionen die nicht nur eine Möglichkeit kennen magische Methoden abzufragen/zu verwenden. `iter()` wäre da ein Beispiel. Das stützt sich auf die `__iter__()`-Methode. Allerdings fällt die Funktion bei Objekten die diese Methode nicht haben auf `__getitem__()` mit Zahlen von 0 aufwärts zurück bis ein `IndexError` ausgelöst wird. Dass heisst hier ist ``iter(obj)`` und ``obj.__iter__()`` nicht äquivalent. Selbst Funktionen die das *jetzt* nicht machen, können vielleicht in späteren Python-Versionen auch andere „magische” Methoden verwenden, wenn sich diese APIs mal ändern sollten.
DanJJo
User
Beiträge: 90
Registriert: Mittwoch 13. Februar 2013, 18:35

also ich hab kA wie ich dem sqlite3.row object seine info entziehen kann. Es ist traurig, dass man nicht einfach mal eine hilfe bekommt die sagt...nimm funktion strconvert() und fertig .... :(
BlackJack

@DanJJo: Das ist ein Grunddatentyp in Python. Den sollte man kennen wenn man ein Grundlagen-Tutorial durchgearbeitet hat. Und das sollte man tun, wenn man mit Python programmieren will. Wenn Dir jetzt jemand sagt wie's geht, und es ist wirklich total einfach, dann kommst Du sehr wahrscheinlich bald wieder mit so einer trivialen Grundlagenfrage. Wir sind hier nicht dazu da das Tutorial vorzulesen. Und niemand kann Dir die Einarbeitung in eine Programmiersprache abnehmen.
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

Probier das mal:

Botte App:

Code: Alles auswählen

sql ="""SELECT bla FROM blabla ORDER BY blub ASC"""
cur.execute(sql)
result = cur.fetchall()
anzeige = template('template.tpl',rows=result) #Oder wie du dein Templ auch immer nennst
t = Template(tpl)
return t.substitute(anzeige)
Template:

Code: Alles auswählen

%for row in rows:
  <tr>
  %for col in row:
    <td>{{col}}</td>
  %end
  </tr>
%end
Benutzeravatar
/me
User
Beiträge: 3554
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

DanJJo hat geschrieben:nun steht in row meine Info in dem format....

(u 'bla',)

komm ich irgendwie einfach nur an das "bla" ohne die utf geschichte drum?
Du gehst schon von falschen Voraussetzungen aus. Was du siehst ist die Repräsentation des Inhalts, nicht der Inhalt selber. Es handelt sich offensichtlich um ein Tupel.

Zudem hat die String-Repräsentation u'bla' nichts mit einer UTF-Codierung zu tun. Im Gegenteil, das führende u zeigt dir an, dass es sich um einen Unicodestring handelt.

Du solltest wirklich zumindest die ersten Kapitel des Tutorials durchgehen bevor du weitermachst. Du wirst sonst immer wieder auf Grundlagenprobleme stoßen die dich bei der Entwicklung aufhalten und die du glaubst nicht selber lösen zu können.
DanJJo
User
Beiträge: 90
Registriert: Mittwoch 13. Februar 2013, 18:35

Ihr habt ja recht. :roll:

aber eine Design-frage stell ich trotzdem mal...

nun hab ich ein Login auf der Homepage die aus mehreren templates besteht....

main.tpl,
login.tpl,
register.tpl,
suche.tpl,
usw.

auf jedem dieser *.tpl ist nun ein Bereich bei dem Login / Register steht (beide natürlich verlinkt) Wird nun ein User eingelogged setze ich ein cookie, um ihn wieder zu erkennen usw.

jetzt hätte ich natürlich gerne, dass aus dem Login / Register bereich ein User / Benutzerprofil bereich wird. Jetzt hatte ich natürlich die idee, die *.tpl für eingelogged und nicht eingelogged zu machen aber dann hat man doch so viele *.tpl für eine solch kleine Änderung...das muss doch auch einfacher gehen mit irgendeinem Dynamischen breich, einer If abfrage nach dem cookie etc.?! kann mir da einer ein Tipp geben in welche richtung ich das Designen muss und unter welcher rubrik ich da mal schauen sollte?!

Danke
Antworten