Django небольшие байты на модели, какой тип должен использоваться для моделирования? - PullRequest
0 голосов
/ 03 октября 2018

У меня есть модель, в которой я хочу хранить несколько маленьких (2-4 байта) байтовых строк (например: b'foo' или b'\x02').Я задаюсь вопросом о том, как лучше всего смоделировать их на моей модели Django.Я думал, что смогу использовать CharField, но это не работает, как я ожидал.BinaryField, кажется, работает, но я не уверен, подходит ли он для полей короткой длины (опять же, обычно 2-4 байта)

Учитывая модель:

class Foobar(models.Model):
    charfield = models.CharField(max_length=10)
    binaryfield = models.BinaryField()

КогдаЯ делаю:

>>> fb1 = Foobar()
>>> fb1.charfield = b'\0000'
>>> fb1.binaryfield = b'\0000'
>>> fb1.save()

И затем читаю запись обратно:

>>> read = Foobar.objects.get(id=fb1.id)
>>> read.charfield == b'\0000'
False
>>> read.binaryfield == b'\0000'
True

Я бы ожидал, что обе проверки на равенство будут True.Кроме того, документы , кажется, указывают, что фильтрация набора запросов в двоичном поле недопустима (и это то, что мне нужно уметь).Сказав это, мне кажется, что это работает:

>>> Foobar.objects.filter(binaryfield__in=[b'\0000', b'blarg'])
<QuerySet [<Foobar: Foobar object>]>

Я что-то упускаю из CharField?Является ли BinaryField подходящим выбором здесь?Или есть лучшая альтернатива?

В случае, если это имеет значение, я использую Django 1.11 (самая последняя версия LTS в настоящее время), и это проект, работающий на Python 3.6.

1 Ответ

0 голосов
/ 03 октября 2018

BinaryField - правильный выбор для этого - начиная с Django 2.1.Вы, к сожалению, правы, что до этого документация содержала предупреждение о «невозможно отфильтровать набор запросов по значению BinaryField».Учитывая, что вы смогли сделать именно это, вы, возможно, захотите исследовать и точно узнать, какие здесь ограничения.

Передача простой байтовой строки в CharField определенно неверна.Django неявно преобразует вашу байтовую строку в Unicode, прежде чем кодировать ее для базы данных, и это приведет к ошибкам.Например, существуют последовательности байтов, которые не являются допустимыми представлениями utf-8: try Foobar.objects.create(charfield=b'\xf8').

Другой вариант - это явное кодирование байтового поля самостоятельно (скажем, в шестнадцатеричных символах), возможно, путем создания настраиваемого поля,Но тогда вы должны делать то же самое всякий раз, когда вы filter().Ужасно.

Поэтому попытайтесь заставить BinaryField работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...