代码之家  ›  专栏  ›  技术社区  ›  the_void

Django:如何对mysql varbinary十六进制字段建模?

  •  3
  • the_void  · 技术社区  · 15 年前

    我想做A型 VARBINARY django v1.1.1中的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的一个bug?)

    问题是你将如何模拟这样一个领域?

    附:与这个问题有关的是这张票[2],3年后还开着:(

    [1]Django:编写自定义模型字段

    〔2〕 http://code.djangoproject.com/ticket/2417

    3 回复  |  直到 10 年前
        1
  •  1
  •   the_void    10 年前

    问题在于Django创建数据库表的方式,并且与数据库排序相关。

    我的解决方法如下:

    • 将表字符集更改为 utf8 和排序规则 utf8_bin
    • 已将二进制字段从 VARCHAR VARBINARY 在mysql表中
    • 用于 to_python 方法 return hexlify(value)
        2
  •  0
  •   Community Sam Holder    7 年前

    你提到的同一张票也有 a patch 它应该为实现这个字段提供一些指针。

    在任何情况下,把它存储在charfield中有什么真正的问题?

    即使要实现一个bin字段,也可以扩展models.charfield,并将其转换为tou python方法中的十六进制。

    同样的问题也在前面得到了回答: Storing a binary hash value in a Django model field

        3
  •  0
  •   Denis Otkidach    15 年前

    MySQL既不存储varbinary字段的十六进制表示,也不要求在insert语句中使用它。与varchar的唯一区别是mysql使用二进制排序规则。您可以将任何8位字符串作为参数传递给它。