aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/topics/credits.md2
-rw-r--r--docs/topics/release-notes.md4
-rw-r--r--rest_framework/fields.py1
-rw-r--r--rest_framework/renderers.py3
-rw-r--r--rest_framework/serializers.py11
-rw-r--r--rest_framework/tests/serializer.py26
6 files changed, 45 insertions, 2 deletions
diff --git a/docs/topics/credits.md b/docs/topics/credits.md
index 9e59d678..dfa1ee0f 100644
--- a/docs/topics/credits.md
+++ b/docs/topics/credits.md
@@ -73,6 +73,7 @@ The following people have helped make REST framework great.
* Michael van de Waeter - [mvdwaeter]
* Reinout van Rees - [reinout]
* Michael Richards - [justanotherbody]
+* Ben Roberts - [roberts81]
Many thanks to everyone who's contributed to the project.
@@ -181,3 +182,4 @@ To contact the author directly:
[mvdwaeter]: https://github.com/mvdwaeter
[reinout]: https://github.com/reinout
[justanotherbody]: https://github.com/justanotherbody
+[roberts81]: https://github.com/roberts81
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 867b138b..c2fe3f64 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -4,6 +4,10 @@
>
> — Eric S. Raymond, [The Cathedral and the Bazaar][cite].
+## Master
+
+* Bugfix: Fix `RegexField` to work with `BrowsableAPIRenderer`
+
## 2.1.6
**Date**: 23rd Nov 2012
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index ff39fac4..c28a9695 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -817,6 +817,7 @@ class EmailField(CharField):
class RegexField(CharField):
type_name = 'RegexField'
+ form_field_class = forms.RegexField
def __init__(self, regex, max_length=None, min_length=None, *args, **kwargs):
super(RegexField, self).__init__(max_length, min_length, *args, **kwargs)
diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py
index 25a32baa..1220bca1 100644
--- a/rest_framework/renderers.py
+++ b/rest_framework/renderers.py
@@ -320,6 +320,9 @@ class BrowsableAPIRenderer(BaseRenderer):
if getattr(v, 'choices', None) is not None:
kwargs['choices'] = v.choices
+ if getattr(v, 'regex', None) is not None:
+ kwargs['regex'] = v.regex
+
if getattr(v, 'widget', None):
widget = copy.deepcopy(v.widget)
kwargs['widget'] = widget
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 43bfda83..5edd46f5 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -22,7 +22,16 @@ class DictWithMetadata(dict):
"""
A dict-like object, that can have additional properties attached.
"""
- pass
+ def __getstate__(self):
+ """
+ Used by pickle (e.g., caching).
+ Overriden to remove metadata from the dict, since it shouldn't be pickled
+ and may in some instances be unpickleable.
+ """
+ # return an instance of the first dict in MRO that isn't a DictWithMetadata
+ for base in self.__class__.__mro__:
+ if not isinstance(base, DictWithMetadata) and isinstance(base, dict):
+ return base(self)
class SortedDictWithMetadata(SortedDict, DictWithMetadata):
diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py
index 18e24b71..455fa270 100644
--- a/rest_framework/tests/serializer.py
+++ b/rest_framework/tests/serializer.py
@@ -1,4 +1,4 @@
-import datetime
+import datetime, pickle
from django.test import TestCase
from rest_framework import serializers
from rest_framework.tests.models import (Album, ActionItem, Anchor, BasicModel,
@@ -699,3 +699,27 @@ class BlankFieldTests(TestCase):
"""
serializer = self.not_blank_model_serializer_class(data=self.data)
self.assertEquals(serializer.is_valid(), False)
+
+
+#test for issue #460
+class SerializerPickleTests(TestCase):
+ """
+ Test pickleability of the output of Serializers
+ """
+ def test_pickle_simple_model_serializer_data(self):
+ """
+ Test simple serializer
+ """
+ pickle.dumps(PersonSerializer(Person(name="Methusela", age=969)).data)
+
+ def test_pickle_inner_serializer(self):
+ """
+ Test pickling a serializer whose resulting .data (a SortedDictWithMetadata) will
+ have unpickleable meta data--in order to make sure metadata doesn't get pulled into the pickle.
+ See DictWithMetadata.__getstate__
+ """
+ class InnerPersonSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Person
+ fields = ('name', 'age')
+ pickle.dumps(InnerPersonSerializer(Person(name="Noah", age=950)).data)