Seite 1 von 1

bottle: Korrektes Auslesen eines UTF-8 codierten Datensatzes

Verfasst: Freitag 11. Januar 2013, 23:58
von JayOne
Hallo Zusammen,

ich bin gerade dabei zu Testzwecken mir eine Web-App mit bottle zu schreiben, dabei habe ich aber ein Problem mit den Posts, bei denen z.B. Umlaue wie Ä oder Ü nur mit "À" oder einem Zeichen, das wie eine Raute aussieht, dargestellt wird.

Code: Alles auswählen

   #!/usr/bin/python3.2
   # -*- coding: utf-8 -*-
  
   import pymongo
   from bottle import route, run, debug, template, static_file, request
   
   con = pymongo.Connection('localhost', 27017)
   db = con['test_db']
   
 @route('/show')
  def show_item():
     col = db['test_2']
     db_entries = col.find()
     output = template('static/template/show_entries', entries=db_entries)
     return output
 
 @route('/new', method='GET')
 def new_item():
     if request.GET.get('save','').strip():
         new = request.GET.get('item','').strip()
         col = db['test_2']
         insert = {'Inhalt': new,
                 'Thema':'Add'}
                                           #Mein Versuch eines Lösungsansatzes war es hier "new" mit .encode('utf-8') in die DB zu schreiben,
                                           um den Datensatz beim Auslesen mit .decode('utf-8') korrekt auszugeben
         col.save(insert)
     else:
         return template('static/template/make_entry.tpl')
debug(True)
run(port=8110, reloader=True)
Der Code so ist, mit MongoDB und den Templates, voll funktionsfähig, jedoch mit obigem Prob. Ich halte es für ein Codierungsproblem, da ich manuel mir die DB angesehen habe und die Datensätze so schon gespeichert werden, also (denke ich mir) liegt der Fehler iwo in der Speicherung/Übermittlung der Daten. Jedoch weiss ich nicht wo ich (sofern ich das mit .encode()) lösen könnte, die Decodierung ansetzen sollte. Ich schätze mal es ist nur wieder ein Anfängerproblem, was ich gerne übersehe, aber ich weiss da momentan nicht weiter.

Falls mir jmd ein Tipp geben kann bitte mitteilen :-)

Re: bottle: Korrektes Auslesen eines UTF-8 codierten Datensa

Verfasst: Samstag 12. Januar 2013, 00:45
von Sirius3
Hallo JayOne,

mongoDB arbeitet ausschließlich mit utf8 so dass Python-Unicode-Strings richtig verarbeitet werden.

Benutzt Du das richtige Encoding für Deine html-Seiten?

Grüße
Sirius

Re: bottle: Korrektes Auslesen eines UTF-8 codierten Datensa

Verfasst: Samstag 12. Januar 2013, 07:28
von JayOne
Danke für die schnelle Antwort.

Als utf-8 codierung nutze ich: <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

Sonst habe ich alles auf default, da ich die Syntax für ein ordentliches en-/decoding nicht kenne. Ich habe diesen Meta-Tag, aber funktionieren tut es trotzdem nicht, muss man den Datensatz vorher nochmals codieren und später decodieren?

Re: bottle: Korrektes Auslesen eines UTF-8 codierten Datensa

Verfasst: Samstag 12. Januar 2013, 07:56
von JayOne
Ich habe jetzt versucht, den Datensatz vor dem schreiben in die DB nach utf8 zu codieren und dann im tpl zu decodieren:

Code: Alles auswählen

<!DOCTYPE html>
<html>
    <head>
        <title>Something of interest</title>
        <link rel="stylesheet" type="text/css" href="/show/static/css/format.css">
        <meta charset="utf-8">
    </head>
    <body>
         <p>The open items are as follows:</p>
            <table border="1">
            %for i in entries:
            <tr><td>{{i['Inhalt'].decode()}}</td></tr>
            %end
            </table>
    </body>
</html>
Rein technische gesehen funktioniert das alles, aber trotz der codierung nach utf8 vor dem schreiben in die DB werden die so komisch dargestellt. Also ich teste über den immer gleich was in die DB geschrieben wurde und da steht zwar in der db der Datensatz als byte-Objekt, jedoch bei der Ausgabe (mit dem .decode()-Befehl) ist wieder diese falsche Darstellung.

Re: bottle: Korrektes Auslesen eines UTF-8 codierten Datensa

Verfasst: Samstag 12. Januar 2013, 10:21
von Sirius3
An welcher Stelle genau hast Du ein Encoding-Problem?

1. Mit der Zeile

Code: Alles auswählen

new = request.GET.get('item','').strip()
erhältst Du ein bytes-Objekt, das Du mit new.decode('utf-8') in einen
String umwandeln kannst.

2. Bei col.save(insert) solltest Du dann die Strings richtig in die Datenbank schreiben.

3. Beim Auslesen aus der Datenbank bekommst Du wieder die richtigen Strings zurück.

4. Für die Ausgabe als html encodest Du sie wieder als 'utf-8'

5. Der Browser stellt alle Zeichen korrekt dar.

Wenn Du nach Punkt 5 Probleme hast, ab welchem Punkt erhältst Du nicht das erwartete?

Re: bottle: Korrektes Auslesen eines UTF-8 codierten Datensa

Verfasst: Samstag 12. Januar 2013, 20:02
von JayOne
Ich habe das nach deinem Ansatz gemacht, die Vorgehensweise ist kein Problem; So habe ich das verstanden

Code: Alles auswählen

new = request.GET.get('item','').strip()
new_dataset = new.decode('utf-8')
insert = {'Inhalt': new_dataset, 'Thema':'Add'}
col = db['test_2']
col.save(insert)
Jedoch bekomme ich dann den Fehler:

Code: Alles auswählen

Traceback (most recent call last):
  File "/usr/lib/python3.2/site-packages/bottle-0.11.4-py3.2.egg/bottle.py", line 763, in _handle
    return route.call(**args)
  File "/usr/lib/python3.2/site-packages/bottle-0.11.4-py3.2.egg/bottle.py", line 1572, in wrapper
    rv = callback(*a, **ka)
  File "little_d_test.py", line 21, in new_item
    new_dataset = new.decode('utf-8')
 AttributeError: 'str' object has no attribute 'decode'
Was ist daran jetzt falsch :?: Nach der Fehlermeldung zu urteilen ist demnach doch "new" ein str-Objekt und ich könnte es als str in die DB schreiben, oder nicht?

Re: bottle: Korrektes Auslesen eines UTF-8 codierten Datensa

Verfasst: Samstag 12. Januar 2013, 22:56
von Sirius3
@JayOne: also liefert request.GET zwar unicode-Strings, die aber noch utf-8-kodiert sind.
Kurze Internetsuche ergab, eine zusätzliche Dekodierung:

Code: Alles auswählen

params = request.GET.decode()
new = params['item']

Re: bottle: Korrektes Auslesen eines UTF-8 codierten Datensa

Verfasst: Samstag 12. Januar 2013, 23:08
von JayOne
Find ich echt super, dass du noch so spät geschaut hast :mrgreen:

Ich habe auch gesucht, um zu finden was genau der Rückgabewert von request.GET ist, aber leider nicht gefunden.
Genau das war es auch, wo das Prob lag.

Könntest du mir vllt nochmal sagen wo/was du gesucht hast um das zu finden?