Weiß jemand, wie ich möglichst einfach von einem (AJAX-) Javascript aus, MySQL-Daten mit Python empfangen kann?
Praktisch soll es so aussehen, dass beispielsweise eine ID von .js an das .py übergeben wird. Als Antwort des Skriptes soll dann das Ergebnis der sql-query ausgegeben werden. Wie implementiert man so etwas?
Python und AJAX
Das ist jetzt eher eine JavaScript, denn eine Python-Frage. Du musst mit JavaScript über das `XMLHttpRequest` Objekt eine Anfrage an den Webserver schicken die im einfachsten Fall von einem CGI-Skript bearbeitet wird. Datenübergabe geschieht per `GET` also in der URL kodiert oder per `POST`. Genauso wie bei CGI.
Das Skript auf dem Server bearbeitet die Anfrage und schickt eine Antwort zurück. Die kann in jedem x-beliebigen Format sein und muss dann vom JavaScript im Browser ausgewertet werden. Üblicherweise nimmt man als Format XML (da kommt das X in AJAX her), man kann aber auch andere z.B. JSON nehmen.
Das Ergebnis muss man dann per JavaScript darstellen, zum Beispiel indem man das bereits angezeigte HTML Dokument per DOM API verändert.
Es gibt JavaScript Bibliotheken die das ganze ein wenig vereinfachen, zum Beispiel die kleinen Unterschiede in den verschiedenen Browsern vor dem Programmierer verstecken. MochiKit finde ich persönlich ganz nett, vor allem weil es eine Menge Funktionen bietet, die man aus Python kennt und schätzt.
Das Skript auf dem Server bearbeitet die Anfrage und schickt eine Antwort zurück. Die kann in jedem x-beliebigen Format sein und muss dann vom JavaScript im Browser ausgewertet werden. Üblicherweise nimmt man als Format XML (da kommt das X in AJAX her), man kann aber auch andere z.B. JSON nehmen.
Das Ergebnis muss man dann per JavaScript darstellen, zum Beispiel indem man das bereits angezeigte HTML Dokument per DOM API verändert.
Es gibt JavaScript Bibliotheken die das ganze ein wenig vereinfachen, zum Beispiel die kleinen Unterschiede in den verschiedenen Browsern vor dem Programmierer verstecken. MochiKit finde ich persönlich ganz nett, vor allem weil es eine Menge Funktionen bietet, die man aus Python kennt und schätzt.
Ich fürchte, ich hab mich etwas umständlich ausgedrückt.
Konkret will ich wissen, ob man das Beispiel aus dem AJAX-Tutorial (AJAX SERVER Page) unter http://www.w3schools.com/ajax/ajax_database.asp statt mit VBScript auch mit Python implementieren kann.
Trotzdem vielen Dank für die Antwort!!
Konkret will ich wissen, ob man das Beispiel aus dem AJAX-Tutorial (AJAX SERVER Page) unter http://www.w3schools.com/ajax/ajax_database.asp statt mit VBScript auch mit Python implementieren kann.
Trotzdem vielen Dank für die Antwort!!
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hi mc_mak!mc_mak hat geschrieben:Konkret will ich wissen, ob man das Beispiel aus dem AJAX-Tutorial (AJAX SERVER Page) unter http://www.w3schools.com/ajax/ajax_database.asp statt mit VBScript auch mit Python implementieren kann.
Ja, das kann man. Ich greife in AJAX-Belangen aber immer auf eine kleine Bibliothek zurück, die mir das Arbeiten damit ein wenig erleichtert.
Da ich mich aber immer nur mit AJAX in Verbindung mit Zope befasst habe, wusste ich jetzt auf Anhieb nicht, wie das mit AJAX ohne so einen Server wie Zope läuft. Deshalb habe ich ein kleines Beispiel gestrickt.
Meinen CGI-Testordner habe ich einfach mal im Ganzen gezippt und auf meine Website hochgeladen.
http://gerold.bcom.at/python/python_code/cgi_test.zip
In dieser Zip-Datei befindet sich der Testserver von Jens. Diesen muss du starten. Danach gibst du in deinem Browser "http://localhost:8888/" ein und schon solltest du vom Testserver eine Übersicht bekommen.
Der AJAX-Test befindet sich im Ordner "cgi_test\cgi-bin\ajax_test".
Das Beispiel zeigt auf, wie du Daten an ein Python-CGI-Skript übergeben kannst und wie du korrekten XMLRPC-Code zurück lieferst. In der HTML-Datei sieht man deutlich, wie einfach es mit mini-ajax ist, den Inhalt eines Tags auszutauschen.
Hier die Daten, aber ohne CGI-Server und Datenstruktur:
index.html:
Code: Alles auswählen
<html>
<head>
<script src="ajax.js"></script>
<script language="JavaScript">
function get_time() {
id = document.getElementById("txt_id").value;
url = "/cgi-bin/ajax_test/time_seconds.py?id=" + id;
ajax.update(url, "ergebnis");
}
</script>
</head>
<body>
<form>
Id: <input type="text" id="txt_id">
<input type="button" value="Anfrage starten" onClick="get_time()">
</form>
<p id="ergebnis">
[Ergebnis]
</p>
</body>
</html>
Code: Alles auswählen
// mini/ajax.js - http://timmorgan.org/mini
function $(e){if(typeof e=='string')e=document.getElementById(e);return e};
function collect(a,f){var n=[];for(var i=0;i<a.length;i++){var v=f(a[i]);if(v!=null)n.push(v)}return n};
ajax={};
ajax.x=function(){try{return new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{return new ActiveXObject('Microsoft.XMLHTTP')}catch(e){return new XMLHttpRequest()}}};
ajax.serialize=function(f){var g=function(n){return f.getElementsByTagName(n)};var nv=function(e){if(e.name)return encodeURIComponent(e.name)+'='+encodeURIComponent(e.value);else return ''};var i=collect(g('input'),function(i){if((i.type!='radio'&&i.type!='checkbox')||i.checked)return nv(i)});var s=collect(g('select'),nv);var t=collect(g('textarea'),nv);return i.concat(s).concat(t).join('&');};
ajax.send=function(u,f,m,a){var x=ajax.x();x.open(m,u,true);x.onreadystatechange=function(){if(x.readyState==4)f(x.responseText)};if(m=='POST')x.setRequestHeader('Content-type','application/x-www-form-urlencoded');x.send(a)};
ajax.get=function(url,func){ajax.send(url,func,'GET')};
ajax.gets=function(url){var x=ajax.x();x.open('GET',url,false);x.send(null);return x.responseText};
ajax.post=function(url,func,args){ajax.send(url,func,'POST',args)};
ajax.update=function(url,elm){var e=$(elm);var f=function(r){e.innerHTML=r};ajax.get(url,f)};
ajax.submit=function(url,elm,frm){var e=$(elm);var f=function(r){e.innerHTML=r};ajax.post(url,f,ajax.serialize(frm))};
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
print "Content-Type: text/xml; charset=iso-8859-1"
print
import cgi
import cgitb; cgitb.enable()
import xmlrpclib as xlib
import time
# So bekommst du die ID (damit kannst du machen was du willst):
# http://localhost:8888/cgi_bin/ajax_test/time_seconds.py?id=2
fs = cgi.FieldStorage()
id = int(fs.getvalue("id", "0"))
data = (time.time(), )
print xlib.dumps(data, methodresponse = True, encoding = "iso-8859-1")
lg
Gerold

http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hi!
So wie es aussieht, funktioniert oben aufgezeigtes Beispiel auch dann, wenn ich die Daten unstrukturiert, also als reinen Text zurück gebe:
mfg
Gerold

So wie es aussieht, funktioniert oben aufgezeigtes Beispiel auch dann, wenn ich die Daten unstrukturiert, also als reinen Text zurück gebe:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
print "Content-Type: text/plain; charset=iso-8859-1"
print
#import cgi
#import cgitb; cgitb.enable()
#import xmlrpclib as xlib
import time
# So bekommst du die ID (damit kannst du machen was du willst):
# http://localhost:8888/cgi_bin/ajax_test/time_seconds.py?id=2
#fs = cgi.FieldStorage()
#id = int(fs.getvalue("id", "0"))
#data = (time.time(), )
#print xlib.dumps(data, methodresponse = True, encoding = "iso-8859-1")
print time.time()
Gerold

http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Habe mich auch mal an einem AJAX Beispiel in Python versucht. Auf Browserseite kommt MochiKit zum Einsatz und auf der Serverseite simplejson und eine SQLite3 Datenbank die von AmaroK mit Daten gefüttert wurde.
Der XHTML Quelltext:
Das dazugehörige `ajax_test.js`:
Und noch die Python-Datei, welche die Anfrage entgegennimmt, die Datenbank befragt und das Ergebnis zurück an den Browser sendet:
Der XHTML Quelltext:
Code: Alles auswählen
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<title>AJAX CGI Test</title>
<script type="text/javascript" src="MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="ajax_test.js"></script>
</head>
<body>
<h1>AJAX CGI Test</h1>
<p>
Dieser kleine Test verbindet <a href="http://mochikit.com/">MochiKit</a>,
<a href="http://www.python.org/">Python</a> und
<a href="http://www.sqlite.org/">SQLite</a> zu einer kleinen AJAX
Demonstration.
</p>
<p>Abgefragt wird eine SQLite Datenbank, die mit AmaroK erstellt wurde.</p>
<h2>Abfrage</h2>
<form action="" onsubmit="search(); return false;">
<p>Künstlername
<input type="text" id="searchkey" />
<input type="submit" value="Suche" />
</p>
</form>
<h2>Ergebnis</h2>
<div id="result">Hier kommt das Ergebnis hin.</div>
</body>
</html>
Code: Alles auswählen
function search()
{
var result = doSimpleXMLHttpRequest("cgi-bin/ajax_cgi.py",
{artist: $("searchkey").value});
result.addCallbacks(displayResult);
}
function makeRow(cellType, rowData)
{
return TR(null, map(partial(cellType, null), rowData));
}
function makeResultTable(result)
{
return TABLE({border: 1},
makeRow(TH, result.columns),
map(partial(makeRow, TD), result.data));
}
function displayResult(response)
{
var result = evalJSONRequest(response);
var resultNode = DIV(null, P(null, "Künstlername: ", result.artist),
makeResultTable(result));
replaceChildNodes($("result"), resultNode);
}
Code: Alles auswählen
#!/usr/bin/env python
import cgi
import cgitb; cgitb.enable()
import sys
import simplejson
from pysqlite2 import dbapi2 as sqlite
print 'Content-Type: text/plain'
print
request = cgi.FieldStorage()
artist = request.getfirst('artist', None)
connection = sqlite.connect('collection.db')
cursor = connection.cursor()
cursor.execute('SELECT DISTINCT album.name, year.name'
' FROM tags'
' JOIN artist ON artist.id = tags.artist'
' JOIN album ON album.id = tags.album'
' JOIN year ON year.id = tags.year'
' WHERE artist.name = ?'
' ORDER BY year.name',
(artist,))
result = cursor.fetchall()
connection.close()
result_object = {'artist': artist,
'columns': ['Album', 'Jahr'],
'data': result}
simplejson.dump(result_object, sys.stdout)
-
- User
- Beiträge: 1790
- Registriert: Donnerstag 28. Oktober 2004, 16:33
- Wohnort: Graz, Steiermark - Österreich
- Kontaktdaten:
Und damit wir vollständig sind hier der pocoo Weg für AJAJSON:
Server: http://trac.pocoo.org/browser/pocoo/tru ... otecall.py
Javascript: http://trac.pocoo.org/browser/pocoo/tru ... ib/Json.js (in Kombination mit MochiKit)
Verwenden kann man das am Client so:
Und unter Pocoo so:
Natürlich kannst du das mit dem Componentsystem nicht 1:1 übernehmen, aber das sollte an dein Framework anpassbar sein.
Server: http://trac.pocoo.org/browser/pocoo/tru ... otecall.py
Javascript: http://trac.pocoo.org/browser/pocoo/tru ... ib/Json.js (in Kombination mit MochiKit)
Verwenden kann man das am Client so:
Code: Alles auswählen
pocoo.lib.RPC.test = function() {
rpc = new pocoo.lib.RPC('/!jsonrpc');
d = rpc.call('core.tests.hello');
d.addCallback(function(result) {
alert(result);
});
}
Code: Alles auswählen
class MyComponent(RemoteCallable):
@export('tests.hello')
def my_method(self, req, name="World"):
return 'Hello %s!' % name
TUFKAB – the user formerly known as blackbird