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:)
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:
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.
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% 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
Ändern Sie abschließend die Standardsortierung, damit dies nicht erneut passiert:
%Vor%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.
Tags und Links unicode django-admin