我有一个模型,我想存储少量的小(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上运行的项目。
答案 0 :(得分:1)
BinaryField
是正确的选择。不幸的是,在此文档之前包含有关“无法过滤BinaryField
值的查询集”的警告。鉴于您能够做到这一点,您可能希望进行调查并确切了解此处的限制。
将纯字节串传递给CharField
绝对是错误的。 Django会在为数据库编码之前将您的字节字符串隐式转换为Unicode,这会产生错误。例如,有些字节序列不是有效的utf-8表示形式:请尝试Foobar.objects.create(charfield=b'\xf8')
。
另一种选择是自己编写字节字段(例如,转换为十六进制字符),这可能是通过创建自定义字段来进行的。但是,无论何时filter()
,您都必须做同样的事情。丑。
因此,请尝试使BinaryField
正常工作。