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 8015)
+++ django/db/backends/mysql/base.py	(working copy)
@@ -21,7 +21,8 @@
     raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__)
 
 from MySQLdb.converters import conversions
-from MySQLdb.constants import FIELD_TYPE
+from MySQLdb.constants import FIELD_TYPE,FLAG
+from django.utils.encoding import smart_unicode
 import re
 
 # Raise exceptions for database warnings if DEBUG is on
@@ -40,10 +41,22 @@
 # behavior as they are signed and include days -- and Django expects time, so
 # we still need to override that.
 django_conversions = conversions.copy()
+
+binstr_conversion = [(FLAG.BINARY, buffer),
+                     (FLAG.BLOB, smart_unicode),
+                     ]
+
 django_conversions.update({
     FIELD_TYPE.TIME: util.typecast_time,
     FIELD_TYPE.DECIMAL: util.typecast_decimal,
     FIELD_TYPE.NEWDECIMAL: util.typecast_decimal,
+    FIELD_TYPE.TINY_BLOB: binstr_conversion,
+    FIELD_TYPE.MEDIUM_BLOB: binstr_conversion,
+    FIELD_TYPE.LONG_BLOB: binstr_conversion,
+    FIELD_TYPE.BLOB: binstr_conversion,
+    FIELD_TYPE.VARCHAR: binstr_conversion,
+    FIELD_TYPE.VAR_STRING: binstr_conversion,
+    FIELD_TYPE.STRING: binstr_conversion,
 })
 
 # 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'<binary data buffer size %d>' % 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',
Index: tests/modeltests/binary/__init__.py
===================================================================
Index: tests/modeltests/binary/tests.py
===================================================================
--- tests/modeltests/binary/tests.py	(revision 0)
+++ tests/modeltests/binary/tests.py	(revision 0)
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+# encoding: utf-8
+
+from models import Document, BinaryFieldTest
+
+import unittest
+
+
+class BlobFieldTests( unittest.TestCase ):
+    
+     def test_blob(self):
+         test_title = u'Hi there! привет!'
+         test_descr = u'описание документа'
+
+         s = '' 
+         for i in range(0,256):
+              s += chr(i)
+         s+= '\xff\xff'
+              
+         
+         test_data = buffer(s)
+         
+         doc = Document(title = test_title,
+                        description = test_descr,
+                        document = test_data)
+         doc.save()
+         doc_id = doc.id
+         doc = None
+         doc = Document.objects.get(id=doc_id)
+         assert doc.title == test_title, type(doc.title)
+         assert doc.description == test_descr, type(doc.description)
+         assert doc.document == test_data, type(doc.document)
+
+class BinaryFieldTests( unittest.TestCase ):
+    
+     def test_binary(self):
+         test_title = u'Hi there! привет!'
+
+         s = '' 
+         for i in range(0,10):
+              s += chr(i)
+
+         s+= '\xff\xff'
+              
+         test_data = buffer(s)
+         
+
+         tst = BinaryFieldTest(title = test_title,
+                          binfield = test_data)
+         tst.save()
+         tst_id = tst.id
+         tst = None
+         tst = BinaryFieldTest.objects.get(id=tst_id)
+         assert tst.title == test_title, type(tst.title)
+         assert tst.binfield == test_data, type(tst.binfield)
+                         
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(BlobFieldTests),
+        unittest.makeSuite(BinaryFieldTests)
+        ))
+
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')
Index: tests/modeltests/binary/models.py
===================================================================
--- tests/modeltests/binary/models.py	(revision 0)
+++ tests/modeltests/binary/models.py	(revision 0)
@@ -0,0 +1,18 @@
+"""
+BlobField and BinaryField tests
+
+"""
+
+from django.db import models
+
+# Create your models here.
+class Document(models.Model):
+    title = models.CharField(max_length=50)
+    description = models.TextField()
+    document = models.BlobField()
+
+class BinaryFieldTest(models.Model):
+    title = models.CharField(max_length=20)
+    binfield = models.BinaryField(max_length=20)
+
+
