Loading django/db/models/fields/__init__.py +12 −1 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ import datetime import decimal import math import warnings from base64 import b64decode, b64encode from itertools import tee from django.db import connection Loading @@ -19,7 +20,7 @@ from django.utils.functional import curry, total_ordering 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 Loading Loading @@ -1318,3 +1319,13 @@ class BinaryField(Field): 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 django/utils/encoding.py +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading tests/serializers_regress/models.py +3 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,9 @@ from django.contrib.contenttypes.models import ContentType # 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() Loading tests/serializers_regress/tests.py +17 −7 Original line number Diff line number Diff line Loading @@ -24,10 +24,11 @@ from django.db import connection, models 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, Loading Loading @@ -116,9 +117,16 @@ 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) 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.data, type(instance.data)) pk, data, type(data), instance, type(instance.data)) ) def generic_compare(testcase, pk, klass, data): Loading Loading @@ -175,8 +183,10 @@ inherited_obj = (inherited_create, inherited_compare) 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"), Loading Loading
django/db/models/fields/__init__.py +12 −1 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ import datetime import decimal import math import warnings from base64 import b64decode, b64encode from itertools import tee from django.db import connection Loading @@ -19,7 +20,7 @@ from django.utils.functional import curry, total_ordering 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 Loading Loading @@ -1318,3 +1319,13 @@ class BinaryField(Field): 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
django/utils/encoding.py +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
tests/serializers_regress/models.py +3 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,9 @@ from django.contrib.contenttypes.models import ContentType # 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() Loading
tests/serializers_regress/tests.py +17 −7 Original line number Diff line number Diff line Loading @@ -24,10 +24,11 @@ from django.db import connection, models 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, Loading Loading @@ -116,9 +117,16 @@ 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) 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.data, type(instance.data)) pk, data, type(data), instance, type(instance.data)) ) def generic_compare(testcase, pk, klass, data): Loading Loading @@ -175,8 +183,10 @@ inherited_obj = (inherited_create, inherited_compare) 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"), Loading