Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added support for serializing BinaryField

  • Loading branch information...
commit d680a3f4477056c69629b0421db4bb254b8c69d0 1 parent 8ee1edd
@claudep claudep authored
View
13 django/db/models/fields/__init__.py
@@ -6,6 +6,7 @@
import decimal
import math
import warnings
+from base64 import b64decode, b64encode
from itertools import tee
from django.db import connection
@@ -19,7 +20,7 @@
from django.utils.text import capfirst
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import smart_text, force_text
+from django.utils.encoding import smart_text, force_text, force_bytes
from django.utils.ipv6 import clean_ipv6_address
from django.utils import six
@@ -1318,3 +1319,13 @@ def get_db_prep_value(self, value, connection, prepared=False):
if value is not None:
return connection.Database.Binary(value)
return value
+
+ def value_to_string(self, obj):
+ """Binary data is serialized as base64"""
+ return b64encode(force_bytes(self._get_val_from_obj(obj))).decode('ascii')
+
+ def to_python(self, value):
+ # If it's a string, it should be base64-encoded data
+ if isinstance(value, six.text_type):
+ return six.memoryview(b64decode(force_bytes(value)))
+ return value
View
2  django/utils/encoding.py
@@ -142,6 +142,8 @@ def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
If strings_only is True, don't convert (some) non-string-like objects.
"""
+ if isinstance(s, six.memoryview):
+ s = bytes(s)
if isinstance(s, bytes):
if encoding == 'utf-8':
return s
View
3  tests/serializers_regress/models.py
@@ -12,6 +12,9 @@
# The following classes are for testing basic data
# marshalling, including NULL values, where allowed.
+class BinaryData(models.Model):
+ data = models.BinaryField(null=True)
+
class BooleanData(models.Model):
data = models.BooleanField()
View
24 tests/serializers_regress/tests.py
@@ -24,10 +24,11 @@
from django.http import HttpResponse
from django.test import TestCase
from django.utils import six
+from django.utils.encoding import force_text
from django.utils.functional import curry
from django.utils.unittest import skipUnless
-from .models import (BooleanData, CharData, DateData, DateTimeData, EmailData,
+from .models import (BinaryData, BooleanData, CharData, DateData, DateTimeData, EmailData,
FileData, FilePathData, DecimalData, FloatData, IntegerData, IPAddressData,
GenericIPAddressData, NullBooleanData, PositiveIntegerData,
PositiveSmallIntegerData, SlugData, SmallData, TextData, TimeData,
@@ -116,10 +117,17 @@ def inherited_create(pk, klass, data):
# test data objects of various kinds
def data_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk)
- testcase.assertEqual(data, instance.data,
- "Objects with PK=%d not equal; expected '%s' (%s), got '%s' (%s)" % (
- pk, data, type(data), instance.data, type(instance.data))
- )
+ if klass == BinaryData and data is not None:
+ testcase.assertEqual(bytes(data), bytes(instance.data),
+ "Objects with PK=%d not equal; expected '%s' (%s), got '%s' (%s)" % (
+ pk, repr(bytes(data)), type(data), repr(bytes(instance.data)),
+ type(instance.data))
+ )
+ else:
+ testcase.assertEqual(data, instance.data,
+ "Objects with PK=%d not equal; expected '%s' (%s), got '%s' (%s)" % (
+ pk, data, type(data), instance, type(instance.data))
+ )
def generic_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk)
@@ -175,8 +183,10 @@ def inherited_compare(testcase, pk, klass, data):
test_data = [
# Format: (data type, PK value, Model Class, data)
- (data_obj, 1, BooleanData, True),
- (data_obj, 2, BooleanData, False),
+ (data_obj, 1, BinaryData, six.memoryview(b"\x05\xFD\x00")),
+ (data_obj, 2, BinaryData, None),
+ (data_obj, 5, BooleanData, True),
+ (data_obj, 6, BooleanData, False),
(data_obj, 10, CharData, "Test Char Data"),
(data_obj, 11, CharData, ""),
(data_obj, 12, CharData, "None"),

0 comments on commit d680a3f

Please sign in to comment.
Something went wrong with that request. Please try again.