Ajax - Bottle mit jQuery - 'str' object is not callable

Django, Flask, Bottle, WSGI, CGI…
Antworten
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Hallo! :)

Ich bin gerade dabei zur Übung eine Ajax-Anwendung mit Bottle und jQuery zu basteln. Allerdings bekomm ich immer diesen Traceback, wenn ich die Anwendung starte und localhost:8080 aufrufe:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Python27\lib\wsgiref\handlers.py", line 85, in run
    self.result = application(self.environ, self.start_response)
TypeError: 'str' object is not callable
Bei allen anderen Anwendungen die ich mit Bottle gemacht habe bekomme ich diesen Fehler nicht.

Das ist mein Code:

Code: Alles auswählen

import json
from bottle import route, run, request

@route('/')
def index():
    return """
    <html>
    <script type="text/javascript"
        src="http://code.jquery.com/jquery-1.5.1.min.js"></script>
    <script type="text/javascript">
        function sendjs() {
            $.post('/rate',
                { rating: $("select").val() },
                function(data) {
                    $("#rating").html("Average rating: "+data.average+"; ratings: "+data.ratings);
                },
                'json'
        };
    </script>
    <body>
    <select>
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
        <option>5</option>
    </select>
    <input type="submit" onclick="sendjs()" />
    <div id="rating">
    </div>
    </body>
    </html>
    """

@route('/rate', method="POST")
def rate():
    rating = request.POST['rating']
    with open("rating.json", "r") as f:
        rating_data = json.load(f)
    average = rating_data['average']
    ratings = rating_data['ratings']

    try:
        rating_data['average'] = (average * ratings + int(rating)) / (ratings + 1)
    except ValueError:
        return {'average': 'NaN', 'ratings': '--'}
    rating_data['ratings'] += 1
    
    with open("rating.json", "w") as f:
        json.dump(rating_data, f)

    return {'average': rating_data['average'], 'ratings': rating_data['ratings']}

run('localhost', port=8080)
(Ja, ich weiß, keine Kommentare und zu lange Zeilen ...)

Woran kann es denn liegen? Ich finde in meinem Code keinen Fehler. :(

Liebe Grüße,
nomnom

Edit:
Ach ja, rating.json sieht so aus:

Code: Alles auswählen

{
 "average": 0.0,
 "ratings": 0
}
Zuletzt geändert von nomnom am Dienstag 8. März 2011, 16:04, insgesamt 1-mal geändert.
BlackJack

@nomnom: Das lässt sich bei mir so noch nicht einmal starten, weil er 'localhost' nicht importieren kann. Da fehlt bei dem `run()`-Aufruf wahrscheinlich das ``host=`` vor dem ersten Argument.

Wenn ich dass dann laufen lasse tut sich nichts wenn ich auf den Submit-Button klicke.

Kann es sein, dass es sich hier nicht um den Quelltext handelt, der bei Dir nicht funktioniert?

PS: Im JavaScript ist wohl ein Syntaxfehler und deswegen ist `sendjs()` dann undefiniert.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

BlackJack hat geschrieben:@nomnom: Das lässt sich bei mir so noch nicht einmal starten, weil er 'localhost' nicht importieren kann. Da fehlt bei dem `run()`-Aufruf wahrscheinlich das ``host=`` vor dem ersten Argument.

Wenn ich dass dann laufen lasse tut sich nichts wenn ich auf den Submit-Button klicke.

Kann es sein, dass es sich hier nicht um den Quelltext handelt, der bei Dir nicht funktioniert?

PS: Im JavaScript ist wohl ein Syntaxfehler und deswegen ist `sendjs()` dann undefiniert.
Danke, BlackJack!
Nachdem ich ``host=`` hinzugefügt habe, konnte ich die Webseite aufrufen, und im JavaScript hab ich den Syntaxfehler behoben (ich hab die Argumente-Liste von $.post() nicht geschlossen).

Code: Alles auswählen

import json
from bottle import route, run, request

@route('/')
def index():
    return """
    <html>
    <script type="text/javascript"
        src="http://code.jquery.com/jquery-1.5.1.min.js"></script>
    <script type="text/javascript">
        function sendjs() {
            $.post('/rate',
                { rating: $("select").val() },
                function(data) {
                    $("#rating").html("Average rating: "+data.average+"; ratings: "+data.ratings);
                },
                'json'
            );
        };
    </script>
    <body>
    <select>
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
        <option>5</option>
    </select>
    <input type="submit" onclick="sendjs()" />
    <div id="rating">
    </div>
    </body>
    </html>
    """

@route('/rate', method="POST")
def rate():
    rating = request.POST['rating']
    with open("rating.json", "r") as f:
        rating_data = json.load(f)
    average = rating_data['average']
    ratings = rating_data['ratings']

    try:
        rating_data['average'] = (average * ratings + int(rating)) / (ratings + 1)
    except ValueError:
        return {'average': 'NaN', 'ratings': '--'}
    rating_data['ratings'] += 1
    
    with open("rating.json", "w") as f:
        json.dump(rating_data, f)

    return {'average': rating_data['average'], 'ratings': rating_data['ratings']}

run(host='localhost', port=8080)
BlackJack

@nomnom: Nach dem ich eine ``ratings.json`` angelegt habe (s.u.) funktioniert das bei mir!?

Code: Alles auswählen

{
    "average": 0,
    "ratings": 0
}
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

BlackJack hat geschrieben:@nomnom: Nach dem ich eine ``ratings.json`` angelegt habe (s.u.) funktioniert das bei mir!?

Code: Alles auswählen

{
    "average": 0,
    "ratings": 0
}
Es sollte mit dem letzten Code den ich gepostet habe dann funktionieren. ;)
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

'localhost' und '8080' sind die Default-Werte, in so fern kann man die auch weglassen.

Ansonsten ist es beim Entwickeln IMHO noch sehr sinnvoll

Code: Alles auswählen

from bottle import debug
...
debug(True)
zu setzen.

Und

Code: Alles auswählen

run(reloader=True)
spart auch Arbeit. :-)

Gruß, noisefloor
Antworten