Django Kopfschmerzen mit einfachen nicht-ASCII-Zeichenfolge

8

Ich habe gerade das folgende Modell erstellt:

%Vor%

Dann auf der Admin-Oberfläche registriert und syncdb'd

Alles in Ordnung, wenn ich einfach nur ASCII-Zeichen hinzufüge. Aber wenn ich eine "Categoria" namens "á" hinzufüge (um etwas zu sagen), bekomme ich:

%Vor%

Meine Django-Version ist 1.1 und meine Datenbank ist 5.1.37-1ubuntu5 mit utf8-Zeichensatz und die Tabelle verwendet eine utf8_bin-Sortierung.

Dieses Problem scheint zu grundlegend, um wahr zu sein, und ich bin ein Django-Neuling, also tut es mir im Voraus leid, wenn mir etwas sehr Einfaches fehlt:)

    
Ezequiel 30.01.2010, 17:56
quelle

6 Antworten

17

Django hat im Allgemeinen sehr gute Unicode-Unterstützung (siehe Django 1.1 "Unicode-Daten" -Dokumentation für Details). In meinem Code finde ich, dass, wenn ich ein Problem mit einfachen Unicode-Funktionen habe, das Problem ist, dass ich Djangos Details nicht gut verstehe, nicht dass Django einen Fehler in seiner Unicode-Unterstützung hat.

Die Seite "Unicode-Daten" sagt uns: "Alle Datenbank-Backends von Django ... konvertieren die aus der Datenbank abgerufenen Strings automatisch in Python-Unicode-Strings. Sie müssen Django nicht einmal sagen, welche Kodierung Ihre Datenbank verwendet: transparent gehandhabt. " Also sollte Ihre einfache return self.nombre eine Python-Unicode-Zeichenfolge zurückgeben.

Die Django 1.1 "Datenbanken" -Seite enthält jedoch eine wichtige Anmerkung zum MySQL-Backend behandelt die utf8_bin -Kollation:

  

... wenn Sie wirklich die Groß- / Kleinschreibung beachten möchten   Vergleiche auf einer bestimmten Spalte oder   Tabelle, würden Sie die Spalte ändern oder   Tabelle, um die utf8_bin-Sortierung zu verwenden.   Die Hauptsache ist dabei zu beachten   Fall ist das, wenn Sie MySQLdb verwenden   1.2.2, das Datenbank-Backend in Django wird dann Bytestrings zurückgeben (stattdessen   von Unicode-Strings) für jedes Zeichen   Felder, die es zurückgibt, erhalten von   Datenbank. Dies ist eine starke Variation   aus Djangos üblicher Praxis   gibt immer Unicode-Strings zurück. Es   liegt bei Ihnen, dem Entwickler, zu handhaben   die Tatsache, dass Sie erhalten werden   Bytestrings, wenn Sie Ihre konfigurieren   Tabelle (n) zur Verwendung der utf8_bin-Sortierung   Django selbst sollte reibungslos funktionieren   mit solchen Spalten, aber wenn Ihr Code   muss bereit sein zu telefonieren   django.utils.encoding.smart_unicode ()   Manchmal, wenn es wirklich funktionieren will   mit konsistenten Daten ...

In Ihrem ursprünglichen Beispiel hat die Spalte "nombre" die Sortierung utf8_bin verwendet. Dies bedeutet, dass self.nombre eine Python-Byte-Zeichenfolge zurückgegeben hat. Wenn Sie es in einen Ausdruck einfügen, der eine Python-Unicode-Zeichenfolge benötigt, hat Python die Standardkonvertierung durchgeführt. Dies entspricht dem self.nombre.decode('ascii') . Und natürlich, .decode('ascii') schlägt fehl, wenn es auf ein Byte über 0x7F stößt, wie die UTF-8 Bytes, die "á" codieren.

Sie haben die zwei Wege gefunden, dieses Problem zu lösen. Die erste besteht darin, die von self.nombre zurückgegebene Python-Byte-Zeichenfolge explizit in eine Python-Unicode-Zeichenfolge zu konvertieren. Ich wette, der folgende einfachere Code hätte funktioniert:

%Vor%

Der zweite Ansatz besteht darin, die MySQL-Kollatierung für die Spalte "nombre" zu ändern, was bewirkt, dass Djangos MySQL-Backend Python-Unicode-Zeichenfolgen anstelle der ungewöhnlichen Byte-Zeichenfolgen zurückgibt. Dann gibt der ursprüngliche Ausdruck eine Python Unicode-Zeichenfolge:

%Vor%

Hoffe, das hilft.

    
Jim DeLaHunt 02.02.2010, 08:55
quelle
7

Dieses Problem kann durch eine kleine Änderung des Django-Codes gelöst werden. Fügen Sie den folgenden Code in django / utils / encoding.py hinzu

%Vor%     
Shuguang Yang 16.06.2011 07:49
quelle
4

Ich hatte dieses Problem in der Produktion und nie auf dem Entwicklungsserver.
Dann erkannte ich, dass neue Tabellen mit utf8_bin collation statt utf8_general_ci erstellt wurden.

Um zu sehen, welche Tabellen konvertiert werden müssen, geben Sie

ein %Vor%

Dann wandeln Sie diese mit utf8_bin collation um, indem Sie

eingeben %Vor%

Ändern Sie abschließend die Standardsortierung, damit dies nicht erneut passiert:

%Vor%     
Dan Abramov 01.11.2011 12:00
quelle
2

Ok ...

%Vor%

macht den Trick.

Aber auch gefunden, dass die Änderung von utf8_bin zu utf8_general_ci den Trick macht, d. h. self.nombre funktioniert wie erwartet.

    
Ezequiel 30.01.2010 18:07
quelle
1

Ich habe das Problem gelöst, indem ich einfach ein Admin Model für das Model erstellt habe und alle Variablen in "list_display" eingeschlossen habe.

    
Özer S. 10.09.2014 14:08
quelle
0

Ich hatte ein ähnliches Problem, als ich kürzlich eine MySQL-Tabelle so geändert habe, dass sie Kollation utf8_bin beim Staging verwendet, während in dev kein Problem (python2.7, Django1.4.2 in beiden Umgebungen) besteht. Ich habe herausgefunden, dass ich in dev MySQL-Python 1.2.4c1 habe und in Staging habe ich 1.2.3. Das Upgrade auf MySQL-Python 1.2.4 hat das Problem für mich gelöst.

    
quanalyst 27.02.2013 22:10
quelle

Tags und Links