Django:如何为 MySQL VARBINARY HEX 字段建模?
Posted
技术标签:
【中文标题】Django:如何为 MySQL VARBINARY HEX 字段建模?【英文标题】:Django: How to model a MySQL VARBINARY HEX Field? 【发布时间】:2010-12-07 22:34:15 【问题描述】:我正在尝试在 Django v1.1.1 中为 VARBINARY
mysql 字段建模。二进制字段存储数据的十六进制表示(即使用INSERT INTO test(bin_val) VALUES X'4D7953514C'
)
阅读 Django 文档[1] 我想出了这个解决方案:
class MyTest(models.Model):
bin_val = BinValField()
class BinValField(models.Field):
__metaclass__ = models.SubfieldBase
def to_python(self, value):
""" DB -> Python """
return ''.join('%X%X' % ((ord(byte)>>4) & 0xF, ord(byte) & 0xF) for byte in value)
def get_db_prep_value(self, value):
""" Python -> DB """
return a2b_hex(value).decode('latin1')
但是这不能正常工作,因为:
Django 对 MySQL 中的二进制数据进行 Unicode 转换 保存新的 MyTest 对象时,get_db_prep_value()
被调用两次(我认为这是 Django 中的错误?)
问题是如何为这样的字段建模?
PS:与这个问题相关的是这张票[2] 3年后仍然打开:(
[1] Django:编写自定义模型字段
[2]http://code.djangoproject.com/ticket/2417
【问题讨论】:
这里的实际问题是什么? 问题是如何在 Django 中正确建模这样一个字段? 【参考方案1】:问题在于 Django 创建数据库表的方式,并且还与数据库排序规则有关。
我解决的方法如下:
将表格字符集更改为utf8
,将排序规则更改为utf8_bin
将 MySQL 表中的二进制字段从 VARCHAR
更改为 VARBINARY
用于to_python
方法return hexlify(value)
【讨论】:
【参考方案2】:MySQL 既不存储 VARBINARY 字段的十六进制表示,也不要求在 INSERT 语句中使用它。与 VARCHAR 的唯一区别是 MySQL 使用二进制排序规则。您可以将任何 8 位字符串作为参数传递给它。
【讨论】:
【参考方案3】:您提到的同一张票也有a patch,它应该为实现该字段提供一些指导。
无论如何,将它存储在 CharField 中的真正问题是什么?
即使您要实现 bin 字段,您也可以扩展 models.CharField 并在 to_python 方法中将其转换为十六进制。
同样的问题之前也有回答:Storing a binary hash value in a Django model field
【讨论】:
以上是关于Django:如何为 MySQL VARBINARY HEX 字段建模?的主要内容,如果未能解决你的问题,请参考以下文章