我用以下代码编写了一个简短的单元测试:
my_object = MyObject()
my_object.data = b'12345'
my_object.save()
saved_object = MyObject.objects.first()
assert saved_object.data == my_object.data
其中 MyObject
定义为:
class MyObject(models.Model):
data = models.BinaryField(default=None)
我希望断言通过,因为我只是保存一些字节数据然后检索它。但是,我最终得到:
AssertionError: assert <memory at 0x10e2abc48> == b'12345'
我猜这与直接将字节字符串保存到二进制字段有关。另一方面,保存成功似乎很奇怪。我很难找到 Django 的 BinaryField
的一些很好的示例用法。谁能向我解释这里发生了什么或我做错了什么?非常感谢。
最佳答案
Django 将 BinaryField
的内容规范化为缓冲区。在 Python2 中为 buffer
和 memoryview
在 Python3 中具体而言。
你可以在源代码中看到:
在 Python2 中,buffer
没有实现比较逻辑,这就是你的断言失败的原因:
Python 2.7.11
>>> m = buffer(b'hello')
>>> m == b'hello'
False
>>> bytes(m) == b'hello'
True
但是它确实实现了其他操作,例如切片和长度:
>>> len(m)
5
>>> m[1:]
'ello'
在 Python 3 中,情况要好得多,因为它实现了所有预期的操作:
Python 3.5.1
>>> m = memoryview(b'hello')
>>> m
<memory at 0x109e8b108>
>>> bytes(m)
b'hello'
>>> m == b'hello'
True
>>> bytes(m) == b'hello'
True
>>> len(m)
5
>>> m[1:]
<memory at 0x109e8b1c8>
我不确定 Django 这样做的原因,但我的猜测是为了提高效率。缓冲区在处理内存方面效率更高。例如,当您切片时,它可以重用相同的内存而不是分配更多的内存。
关于python - Django BinaryField 检索为内存位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34254446/