diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 58dbf977e..86775d061 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -299,6 +299,7 @@ Requires either the `Pillow` package or `PIL` package. The `Pillow` package is Signature and validation is the same as with `FileField`. + --- **Note:** `FileFields` and `ImageFields` are only suitable for use with MultiPartParser, since e.g. json doesn't support file uploads. @@ -306,6 +307,32 @@ Django's regular [FILE_UPLOAD_HANDLERS] are used for handling uploaded files. --- + +## Base64ImageField + +An image representation for Base64ImageField + +Intherited by `ImageField` + +**Signature:** `Base64ImageField()` + + - It takes a base64 image as a string. + - a base64 image: `data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7` + - Base64ImageField accepts only the part after base64, `R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7` + + **Example:** + + #serializer + class UploadedBase64ImageSerializer(serializers.Serializer): + file = serializers.Base64ImageField(required=False) + created = serializers.DateTimeField() + + #use the serializer + file = 'R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' + serializer = UploadedBase64ImageSerializer(data={'created': now, 'file': file}) + + + # Custom fields If you want to create a custom field, you'll probably want to override either one or both of the `.to_native()` and `.from_native()` methods. These two methods are used to convert between the initial datatype, and a primitive, serializable datatype. Primitive datatypes may be any of a number, string, date/time/datetime or None. They may also be any list or dictionary like object that only contains other primitive objects. diff --git a/env/share/man/man1/ipcluster.1.gz b/env/share/man/man1/ipcluster.1.gz new file mode 100644 index 000000000..70cc7ff4a Binary files /dev/null and b/env/share/man/man1/ipcluster.1.gz differ diff --git a/env/share/man/man1/ipcontroller.1.gz b/env/share/man/man1/ipcontroller.1.gz new file mode 100644 index 000000000..212303ed4 Binary files /dev/null and b/env/share/man/man1/ipcontroller.1.gz differ diff --git a/env/share/man/man1/ipengine.1.gz b/env/share/man/man1/ipengine.1.gz new file mode 100644 index 000000000..d661879f3 Binary files /dev/null and b/env/share/man/man1/ipengine.1.gz differ diff --git a/env/share/man/man1/ipython.1.gz b/env/share/man/man1/ipython.1.gz new file mode 100644 index 000000000..badbb5591 Binary files /dev/null and b/env/share/man/man1/ipython.1.gz differ diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 489b9cda2..111b005d8 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -1062,6 +1062,9 @@ class Base64ImageField(ImageField): """ def from_native(self, base64_data): # Check if this is a base64 string + if base64_data in validators.EMPTY_VALUES: + return None + if isinstance(base64_data, basestring): # Try to decode the file. Return validation error if it fails. try: @@ -1081,7 +1084,7 @@ class Base64ImageField(ImageField): def to_native(self, value): # Return url including domain name. - return "" + return value.name def get_file_extension(self, filename, decoded_file): extension = imghdr.what(filename, decoded_file) diff --git a/rest_framework/tests/test_fields.py b/rest_framework/tests/test_fields.py index f0690e965..54949d271 100644 --- a/rest_framework/tests/test_fields.py +++ b/rest_framework/tests/test_fields.py @@ -1011,7 +1011,7 @@ class UploadedBase64Image(object): class UploadedBase64ImageSerializer(serializers.Serializer): - file = serializers.Base64ImageField() + file = serializers.Base64ImageField(required=False) created = serializers.DateTimeField() def restore_object(self, attrs, instance=None): @@ -1025,6 +1025,9 @@ class UploadedBase64ImageSerializer(serializers.Serializer): class Base64ImageSerializerTests(TestCase): def test_create(self): + """ + Test for creating Base64 image in the server side + """ now = datetime.datetime.now() file = 'R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' serializer = UploadedBase64ImageSerializer(data={'created': now, 'file': file}) @@ -1033,24 +1036,25 @@ class Base64ImageSerializerTests(TestCase): self.assertEqual(serializer.object.created, uploaded_image.created) self.assertFalse(serializer.object is uploaded_image) - - def test_creation_failure(self): - """ - Passing file=None should result in an ValidationError - """ - errmsg = 'This field is required.' - now = datetime.datetime.now() - serializer = UploadedBase64ImageSerializer(data={'created': now}) - self.assertFalse(serializer.is_valid()) - self.assertEqual(serializer.errors, {'file': [errmsg]}) - def test_validation_error_with_non_file(self): """ Passing non-base64 should raise a validation error. """ now = datetime.datetime.now() errmsg = "Please upload a valid image." - serializer = UploadedBase64ImageSerializer(data={'created': now, 'file': 'abc'}) self.assertFalse(serializer.is_valid()) - self.assertEqual(serializer.errors, {'file': [errmsg]}) \ No newline at end of file + self.assertEqual(serializer.errors, {'file': [errmsg]}) + + + def test_remove_with_empty_string(self): + """ + Passing empty string as data should cause image to be removed + """ + now = datetime.datetime.now() + file = 'R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' + uploaded_image = UploadedBase64Image(file=file, created=now) + serializer = UploadedBase64ImageSerializer(instance=uploaded_image, data={'created': now, 'file': ''}) + self.assertTrue(serializer.is_valid()) + self.assertEqual(serializer.object.created, uploaded_image.created) + self.assertIsNone(serializer.object.file) \ No newline at end of file