Added support for serializing BinaryField

This commit is contained in:
Claude Paroz 2012-12-15 00:26:08 +01:00
parent 8ee1eddb7e
commit d680a3f447
4 changed files with 34 additions and 8 deletions

View File

@ -6,6 +6,7 @@ import datetime
import decimal import decimal
import math import math
import warnings import warnings
from base64 import b64decode, b64encode
from itertools import tee from itertools import tee
from django.db import connection from django.db import connection
@ -19,7 +20,7 @@ from django.utils.functional import curry, total_ordering
from django.utils.text import capfirst from django.utils.text import capfirst
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ 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.ipv6 import clean_ipv6_address
from django.utils import six from django.utils import six
@ -1318,3 +1319,13 @@ class BinaryField(Field):
if value is not None: if value is not None:
return connection.Database.Binary(value) return connection.Database.Binary(value)
return 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 File

@ -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 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 isinstance(s, bytes):
if encoding == 'utf-8': if encoding == 'utf-8':
return s return s

View File

@ -12,6 +12,9 @@ from django.contrib.contenttypes.models import ContentType
# The following classes are for testing basic data # The following classes are for testing basic data
# marshalling, including NULL values, where allowed. # marshalling, including NULL values, where allowed.
class BinaryData(models.Model):
data = models.BinaryField(null=True)
class BooleanData(models.Model): class BooleanData(models.Model):
data = models.BooleanField() data = models.BooleanField()

View File

@ -24,10 +24,11 @@ from django.db import connection, models
from django.http import HttpResponse from django.http import HttpResponse
from django.test import TestCase from django.test import TestCase
from django.utils import six from django.utils import six
from django.utils.encoding import force_text
from django.utils.functional import curry from django.utils.functional import curry
from django.utils.unittest import skipUnless 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, FileData, FilePathData, DecimalData, FloatData, IntegerData, IPAddressData,
GenericIPAddressData, NullBooleanData, PositiveIntegerData, GenericIPAddressData, NullBooleanData, PositiveIntegerData,
PositiveSmallIntegerData, SlugData, SmallData, TextData, TimeData, PositiveSmallIntegerData, SlugData, SmallData, TextData, TimeData,
@ -116,10 +117,17 @@ def inherited_create(pk, klass, data):
# test data objects of various kinds # test data objects of various kinds
def data_compare(testcase, pk, klass, data): def data_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk) instance = klass.objects.get(id=pk)
testcase.assertEqual(data, instance.data, if klass == BinaryData and data is not None:
"Objects with PK=%d not equal; expected '%s' (%s), got '%s' (%s)" % ( testcase.assertEqual(bytes(data), bytes(instance.data),
pk, data, type(data), instance.data, type(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): def generic_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk) instance = klass.objects.get(id=pk)
@ -175,8 +183,10 @@ inherited_obj = (inherited_create, inherited_compare)
test_data = [ test_data = [
# Format: (data type, PK value, Model Class, data) # Format: (data type, PK value, Model Class, data)
(data_obj, 1, BooleanData, True), (data_obj, 1, BinaryData, six.memoryview(b"\x05\xFD\x00")),
(data_obj, 2, BooleanData, False), (data_obj, 2, BinaryData, None),
(data_obj, 5, BooleanData, True),
(data_obj, 6, BooleanData, False),
(data_obj, 10, CharData, "Test Char Data"), (data_obj, 10, CharData, "Test Char Data"),
(data_obj, 11, CharData, ""), (data_obj, 11, CharData, ""),
(data_obj, 12, CharData, "None"), (data_obj, 12, CharData, "None"),