Django模型上的小字节串,应使用哪种类型的模型?

时间:2018-10-02 21:19:07

标签: python django python-3.x django-models character-encoding

我有一个模型,我想存储少量的小(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。此外,the docs似乎表明不允许过滤Binaryfield上的查询集(这是我将需要做的事情)。话虽如此,它似乎对我有用:

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

我是否缺少有关CharField的内容? BinaryField是这里合适的选择吗?还是有更好的选择?

如果有问题,我正在使用Django 1.11(当前最新的LTS版本),并且这是一个在Python 3.6上运行的项目。

1 个答案:

答案 0 :(得分:1)

从Django 2.1开始,

BinaryField是正确的选择。不幸的是,在此文档之前包含有关“无法过滤BinaryField值的查询集”的警告。鉴于您能够做到这一点,您可能希望进行调查并确切了解此处的限制。

将纯字节串传递给CharField绝对是错误的。 Django会在为数据库编码之前将您的字节字符串隐式转换为Unicode,这会产生错误。例如,有些字节序列不是有效的utf-8表示形式:请尝试Foobar.objects.create(charfield=b'\xf8')

另一种选择是自己编写字节字段(例如,转换为十六进制字符),这可能是通过创建自定义字段来进行的。但是,无论何时filter(),您都必须做同样的事情。丑。

因此,请尝试使BinaryField正常工作。