Index: django/db/models/fields/__init__.py =================================================================== --- django/db/models/fields/__init__.py (revision 8020) +++ django/db/models/fields/__init__.py (working copy) @@ -518,6 +518,25 @@ defaults.update(kwargs) return super(CharField, self).formfield(**defaults) +class BinaryField(Field): + """Sometimes we have fields that need to store a small amount of binary + data. This is different then a varchar on postgresql at least because it + will not allow fields that are just nul bytes. + """ + + def get_internal_type(self): + return "BinaryField" + + +class BlobField(Field): + """Sometimes we have fields that need to store a large amounts of binary + data. + """ + + def get_internal_type(self): + return "BlobField" + + # TODO: Maybe move this into contrib, because it's specialized. class CommaSeparatedIntegerField(CharField): def get_manipulator_field_objs(self): Index: django/db/backends/postgresql/introspection.py =================================================================== --- django/db/backends/postgresql/introspection.py (revision 8020) +++ django/db/backends/postgresql/introspection.py (working copy) @@ -71,6 +71,7 @@ # Maps type codes to Django Field types. DATA_TYPES_REVERSE = { 16: 'BooleanField', + 17: 'BlobField', 21: 'SmallIntegerField', 23: 'IntegerField', 25: 'TextField', Index: django/db/backends/postgresql/creation.py =================================================================== --- django/db/backends/postgresql/creation.py (revision 8020) +++ django/db/backends/postgresql/creation.py (working copy) @@ -4,6 +4,8 @@ # If a column type is set to None, it won't be included in the output. DATA_TYPES = { 'AutoField': 'serial', + 'BinaryField': 'bytea', + 'BlobField': 'bytea', 'BooleanField': 'boolean', 'CharField': 'varchar(%(max_length)s)', 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)', Index: django/db/backends/sqlite3/creation.py =================================================================== --- django/db/backends/sqlite3/creation.py (revision 8020) +++ django/db/backends/sqlite3/creation.py (working copy) @@ -3,6 +3,8 @@ # schema inspection is more useful. DATA_TYPES = { 'AutoField': 'integer', + 'BinaryField': 'BLOB', + 'BlobField': 'BLOB', 'BooleanField': 'bool', 'CharField': 'varchar(%(max_length)s)', 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)', Index: django/db/backends/mysql/base.py =================================================================== --- django/db/backends/mysql/base.py (revision 8020) +++ django/db/backends/mysql/base.py (working copy) @@ -44,6 +44,10 @@ FIELD_TYPE.TIME: util.typecast_time, FIELD_TYPE.DECIMAL: util.typecast_decimal, FIELD_TYPE.NEWDECIMAL: util.typecast_decimal, + FIELD_TYPE.TINY_BLOB: buffer, + FIELD_TYPE.MEDIUM_BLOB: buffer, + FIELD_TYPE.LONG_BLOB: buffer, + FIELD_TYPE.BLOB: buffer, }) # This should match the numerical portion of the version numbers (we can treat Index: django/db/backends/mysql/introspection.py =================================================================== --- django/db/backends/mysql/introspection.py (revision 8020) +++ django/db/backends/mysql/introspection.py (working copy) @@ -75,7 +75,10 @@ return indexes DATA_TYPES_REVERSE = { - FIELD_TYPE.BLOB: 'TextField', + FIELD_TYPE.BLOB: 'BlobField', + FIELD_TYPE.LONG_BLOB: 'BlobField', + FIELD_TYPE.TINY_BLOB: 'BlobField', + FIELD_TYPE.MEDIUM_BLOB: 'BlobField', FIELD_TYPE.CHAR: 'CharField', FIELD_TYPE.DECIMAL: 'DecimalField', FIELD_TYPE.DATE: 'DateField', Index: django/db/backends/mysql/creation.py =================================================================== --- django/db/backends/mysql/creation.py (revision 8020) +++ django/db/backends/mysql/creation.py (working copy) @@ -4,6 +4,8 @@ # If a column type is set to None, it won't be included in the output. DATA_TYPES = { 'AutoField': 'integer AUTO_INCREMENT', + 'BinaryField': 'varbinary(%(max_length)s)', + 'BlobField': 'blob', 'BooleanField': 'bool', 'CharField': 'varchar(%(max_length)s)', 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)', Index: django/db/backends/__init__.py =================================================================== --- django/db/backends/__init__.py (revision 8020) +++ django/db/backends/__init__.py (working copy) @@ -143,8 +143,11 @@ """ from django.utils.encoding import smart_unicode, force_unicode - # Convert params to contain Unicode values. - to_unicode = lambda s: force_unicode(s, strings_only=True) + def to_unicode(s): + if isinstance(s,buffer): + return u'' % len(s) + return force_unicode(s, strings_only=True) + if isinstance(params, (list, tuple)): u_params = tuple([to_unicode(val) for val in params]) else: Index: django/db/backends/postgresql_psycopg2/introspection.py =================================================================== --- django/db/backends/postgresql_psycopg2/introspection.py (revision 8020) +++ django/db/backends/postgresql_psycopg2/introspection.py (working copy) @@ -68,6 +68,7 @@ # Maps type codes to Django Field types. DATA_TYPES_REVERSE = { 16: 'BooleanField', + 17: 'BlobField', 21: 'SmallIntegerField', 23: 'IntegerField', 25: 'TextField',