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 字段建模?的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何为 Django 设计数据库?

django:DetailView 如何为两个模型工作或基于类的视图如何为两个模型工作?

如何为 django 管理员创建选项卡?

如何为 Electron 应用程序服务 Django

如何为 django 创建自定义管理面板

如何为 Django 启用 WSGIPassAuthorization?