2009-02-05 14 views
6

Ich habe einen 20-Byte-Hex-Hash, den ich in einem Django-Modell speichern möchte. Wenn ich ein Textfeld verwende, wird es als Unicode interpretiert und es kommt verstümmelt zurück.Speichern eines binären Hash-Werts in einem Django-Modellfeld

Derzeit bin ich es codieren und Decodierung, die wirklich den Code überfüllt, , weil ich in der Lage sein, durch sie zu filtern.

def get_changeset(self): 
    return bin(self._changeset) 

def set_changeset(self, value): 
    self._changeset = hex(value) 

changeset = property(get_changeset, set_changeset) 

Hier ist ein Beispiel für die Filterung

Change.objects.get(_changeset=hex(ctx.node())) 

Dies ist der Ansatz, der von einem django Entwickler empfohlen wurde, aber ich bin wirklich kämpfen mit der Tatsache abfinden, dass es dieses hässlichen ist nur speicher zwanzig Bytes.

Vielleicht bin ich zu viel von einem puristischen, sondern im Idealfall würde ich in der Lage sein zu schreiben

Change.objects.get(changeset=ctx.node()) 

Die Eigenschaften erlauben Sie mir, schreiben Sie an:

change.changeset = ctx.node() 

Damit so gut wie ich kann, Fragen.

Antwort

4

Ich nehme an, wenn Sie Raw SQL schreiben würden Sie eine Postgres bytea oder MySQL VARBINARY verwenden. Es gibt eine ticket with a patch (markiert "Bedarf testet"), die angeblich ein Feld wie folgt macht (Ticket 2417: Unterstützung für Binärfelder (aka: bytea in postgres und VARBINARY in mysql)).

Sonst könnten Sie wahrscheinlich versuchen, eine custom field type zu schreiben.

+2

n.b. Obwohl diese Antwort vier Jahre alt ist, befindet sich BinaryField nicht in der neuesten Version von Django (1.5), sondern in der aktuellen Entwicklungsversion. –

3

Sie könnten auch Ihre eigene benutzerdefinierte Model Manager schreiben, die die Flucht und Unescaping für Sie erledigt.

3

"Ich habe einen 20-Byte-Hex-Hash, den ich in einem Django-Modell speichern möchte."

Django macht dies. Sie verwenden Hex-Digests, die - technisch gesehen - Strings sind. Keine Bytes.

Verwenden Sie nicht someHash.digest() - Sie erhalten Bytes, die Sie nicht einfach speichern können.

Verwenden Sie someHash.hexdigest() - Sie erhalten eine Zeichenfolge, die Sie problemlos speichern können.

Bearbeiten - Der Code ist nahezu identisch.

Siehe http://docs.python.org/library/hashlib.html

+0

Die Verwendung einer anderen Codierung macht den Code nicht sauberer. Wenn ich noch verschlüsseln und dekodieren muss, habe ich nichts gewonnen. – mbarkhau

+1

Entschuldigung, wenn meine Antwort Sie verwirrt hat. Ich habe es überarbeitet. digest() und hexdigest() sind nahezu identisch. Außer Sie können hexdigest() beibehalten. Sie können Digest() nicht einfach persistieren. –

1

Wenn dieses Problem immer noch von Interesse ist, Disqus' django-bitfield passt die Rechnung:

https://github.com/disqus/django-bitfield

... das Beispiel-Code auf GitHub ist ein wenig verwirrend auf den ersten w/Aufgrund der asininen Variablennamen ist die eigentliche Funktion der Module - im Allgemeinen bin ich kaum die Art von Person, die entweder den kleinen oder den hohen Grund hat, jemandes doof Identifikatoren zur Aufgabe zu bringen ... aber flaggy_foo ?? Srsly, Jungs.Wenn dieses Projekt nicht Ihrem Geschmack entspricht und Sie auf Postgres sind, haben Sie viele ausgezeichnete Möglichkeiten, da viele Leute Code für eine Auswahl von Django-Feldern geschrieben und veröffentlicht haben, die den nativen Typ von Postgres nutzen . Hier ist ein hstore Modellfeld:

https://github.com/jordanm/django-hstore - Ich habe dies verwendet und es funktioniert gut.

Hier ist eine Volltextsuche-Implementierung, die termvector Typen Postgres verwendet:

https://github.com/aino/django-pgindex

Und während ich für dieses spezielle Projekt bürgen kann nicht, gibt es auch Django bytea Felder:

https://github.com/aino/django-arrayfields

+0

Persönlich speichere ich alle meine Hex-Hashes als Text, aber ich musste noch nie Indizes für irgendeinen von ihnen erstellen, also war die Suche nach Leistung kein Problem (ich nehme an, Sie stehen vor so etwas) – fish2000

0

Beginnend mit 1.6, hat Django BinaryField erlaubt, rohe binäre Daten zu speichern. Für Hashes und andere Werte bis zu 128 Bits ist es jedoch effizienter (zumindest mit dem PostgreSQL-Backend), UUIDField in Django 1.8+ zu verwenden.

Verwandte Themen