Ticket #7789: 7789_fields_3.diff

File 7789_fields_3.diff, 3.6 KB (added by arne, 7 years ago)

Similar to 7789_fields_2.diff, but this time returning unicode strings from the binary fields.

  • db/models/fields/__init__.py

     
    150150        # mapped to one of the built-in Django field types. In this case, you
    151151        # can implement db_type() instead of get_internal_type() to specify
    152152        # exactly which wacky database column type you want to use.
    153         data = DictWrapper(self.__dict__, connection.ops.quote_name, "qn_")
    154153        try:
     154            data = get_creation_module().backend_parameters(self, self.__dict__)
     155        except AttributeError:
     156            # No backend_parameters provided in backend
     157            data = self.__dict__
     158        data = DictWrapper(data, connection.ops.quote_name, "qn_")
     159        try:
    155160            return get_creation_module().DATA_TYPES[self.get_internal_type()] % data
    156161        except KeyError:
    157162            return None
  • db/backends/mysql/base.py

     
    2121    raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__)
    2222
    2323from MySQLdb.converters import conversions
    24 from MySQLdb.constants import FIELD_TYPE
     24from MySQLdb.constants import FIELD_TYPE, FLAG
    2525import re
    2626
    2727# Raise exceptions for database warnings if DEBUG is on
     
    3939# TIME columns as timedelta -- they are more like timedelta in terms of actual
    4040# behavior as they are signed and include days -- and Django expects time, so
    4141# we still need to override that.
     42
    4243django_conversions = conversions.copy()
    4344django_conversions.update({
    4445    FIELD_TYPE.TIME: util.typecast_time,
    4546    FIELD_TYPE.DECIMAL: util.typecast_decimal,
    4647    FIELD_TYPE.NEWDECIMAL: util.typecast_decimal,
     48    # By default, mysqldb will return VARCHAR BINARY fields as type str.
     49    # This is a bad idea, as BINARY doesn't indicate that it's arbitrary
     50    # binary data, but that collation uses the binary representation.
     51    # Replacing the list makes it return unicode; mysqldb later adds
     52    # another list entry for non-binary fields.
     53    FIELD_TYPE.VARCHAR: [(FLAG.BINARY, lambda s: s.decode('utf-8'))],
    4754})
    4855
    4956# This should match the numerical portion of the version numbers (we can treat
  • db/backends/mysql/creation.py

     
    55DATA_TYPES = {
    66    'AutoField':         'integer AUTO_INCREMENT',
    77    'BooleanField':      'bool',
    8     'CharField':         'varchar(%(max_length)s)',
     8    'CharField':         'varchar(%(max_length)s) %(binary)s',
    99    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
    1010    'DateField':         'date',
    1111    'DateTimeField':     'datetime',
     
    2020    'PhoneNumberField':  'varchar(20)',
    2121    'PositiveIntegerField': 'integer UNSIGNED',
    2222    'PositiveSmallIntegerField': 'smallint UNSIGNED',
    23     'SlugField':         'varchar(%(max_length)s)',
     23    'SlugField':         'varchar(%(max_length)s) BINARY',
    2424    'SmallIntegerField': 'smallint',
    2525    'TextField':         'longtext',
    2626    'TimeField':         'time',
    2727    'USStateField':      'varchar(2)',
    2828}
     29
     30
     31def backend_parameters(field, field_dict):
     32    """
     33    For MySQL a unique CharField has to be created as a BINARY column as
     34    database level.
     35    """
     36    if field.unique and field.get_internal_type() == 'CharField':
     37        return dict(field_dict, binary='BINARY')
     38    return dict(field_dict, binary='')
Back to Top