Хранение двоичного значения хеша в поле модели Django - PullRequest
8 голосов
/ 05 февраля 2009

У меня есть 20-байтовый шестнадцатеричный хеш, который я хотел бы сохранить в модели django. Если я использую текстовое поле, оно интерпретируется как юникод и возвращается искаженным.

В настоящее время я его кодирую и декодирую, что действительно загромождает код, потому что я должен быть в состоянии фильтровать по нему.

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

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

changeset = property(get_changeset, set_changeset)

Вот пример фильтрации

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

Это подход, который был рекомендован разработчиком django, но я действительно изо всех сил пытаюсь смириться с тем фактом, что просто уродливо хранить двадцать байтов.

Может быть, я слишком большой пурист, но в идеале я мог бы написать

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

Свойства позволяют мне написать:

change.changeset = ctx.node()

Так что это так хорошо, как я могу просить.

Ответы [ 5 ]

4 голосов
/ 06 февраля 2009

"У меня есть двадцатибайтовый шестнадцатеричный хеш, который я хотел бы сохранить в модели django."

Джанго делает это. Они используют шестнадцатеричные дайджесты, которые - технически - строки. Не байт.

Не используйте someHash.digest() - вы получаете байты, которые вы не можете легко сохранить.

Используйте someHash.hexdigest() - вы получите строку, которую вы можете легко сохранить.

Редактировать - Код практически идентичен.

См. http://docs.python.org/library/hashlib.html

4 голосов
/ 05 февраля 2009

Я предполагаю, что если бы вы писали сырой SQL, вы бы использовали байт Postgres или MySQL VARBINARY. Есть билет с патчем (помеченный как «требующий тестирования»), который якобы создает поле наподобие этого (билет 2417: поддержка полей двоичного типа (aka: bytea в postgres и VARBINARY в mysql))

В противном случае вы могли бы попробовать свои силы в написании типа пользовательского поля .

3 голосов
/ 05 февраля 2009

Вы также можете написать свой собственный Диспетчер моделей , который будет выполнять экранирование и эскалацию.

1 голос
/ 09 августа 2017

Начиная с 1.6, Django имеет BinaryField, позволяющий хранить необработанные двоичные данные. Однако для хэшей и других значений до 128 бит более эффективно (по крайней мере с бэкэндом PostgreSQL) использовать UUIDField, доступный в Django 1.8 +.

1 голос
/ 19 сентября 2012

Если этот вопрос все еще интересен, Disqus 'django-bitfield отвечает требованиям:

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

... пример кода на GitHub поначалу немного сбивает с толку фактическую функцию модулей, из-за имен переменных asinine - как правило, я не из тех людей, у кого есть как возвышенное, чтобы принять чьи-то глупые идентификаторы к задаче ... но flaggy_foo ?? Срсли, ребята.

Если этот проект вам не по вкусу, и вы работаете в Postgres, у вас есть много отличных вариантов, так как многие люди написали и выпустили код для ассортимента полей Django, использующих преимущества собственного типа Postgres. Вот поле модели hstore:

https://github.com/jordanm/django-hstore - Я использовал это, и он работает хорошо.

Вот реализация полнотекстового поиска, которая использует типы терминов Postgres:

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

И хотя я не могу поручиться за этот конкретный проект, есть также поля Django bytea:

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

...