From 241be38340dcea9a49ce741ba844171ce02db2bd Mon Sep 17 00:00:00 2001 From: Jens Alm Date: Mon, 15 Oct 2012 09:14:01 +0200 Subject: [PATCH 1/5] Added TextField to recognized fields --- rest_framework/fields.py | 7 +++++++ rest_framework/serializers.py | 1 + 2 files changed, 8 insertions(+) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index bb9a523d6..5d13bd55f 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -409,6 +409,13 @@ class BooleanField(WritableField): return False raise ValidationError(self.error_messages['invalid'] % value) +class TextField(WritableField): + type_name = 'TextField' + + def from_native(self, value): + if isinstance(value, basestring) or value is None: + return value + return smart_unicode(value) class CharField(WritableField): type_name = 'CharField' diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 063300172..0f19956eb 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -381,6 +381,7 @@ class ModelSerializer(Serializer): models.DateField: DateField, models.EmailField: EmailField, models.CharField: CharField, + models.TextField: TextField, models.CommaSeparatedIntegerField: CharField, models.BooleanField: BooleanField, } From 36cc56bc9d49832ca990ba8568903966f46a2938 Mon Sep 17 00:00:00 2001 From: Jens Alm Date: Mon, 15 Oct 2012 10:06:50 +0200 Subject: [PATCH 2/5] Added tests for TextField --- rest_framework/serializers.py | 2 +- rest_framework/tests/serializer.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 0f19956eb..5afbced29 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -381,7 +381,7 @@ class ModelSerializer(Serializer): models.DateField: DateField, models.EmailField: EmailField, models.CharField: CharField, - models.TextField: TextField, + models.TextField: TextField, models.CommaSeparatedIntegerField: CharField, models.BooleanField: BooleanField, } diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 256987ad0..7208d6a54 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -28,6 +28,26 @@ class CommentSerializer(serializers.Serializer): return instance +class LongText(object): + def __init__(self, content): + self.content = content + + def __eq__(self, other): + return all([getattr(self, attr) == getattr(other, attr) + for attr in ('content',)]) + + +class LongTextSerializer(serializers.Serializer): + content = serializers.TextField() + + def restore_object(self, data, instance=None): + if instance is None: + return LongText(**data) + for key, val in data.items(): + setattr(instance, key, val) + return instance + + class BasicTests(TestCase): def setUp(self): self.comment = Comment( @@ -82,6 +102,7 @@ class ValidationTests(TestCase): 'content': 'x' * 1001, 'created': datetime.datetime(2012, 1, 1) } + self.long_text = LongText('test test test test') def test_create(self): serializer = CommentSerializer(self.data) @@ -102,6 +123,14 @@ class ValidationTests(TestCase): self.assertEquals(serializer.is_valid(), False) self.assertEquals(serializer.errors, {'email': [u'This field is required.']}) + def test_update_long_text(self): + data = { + 'content' : 'Lorem ipsum dolor sit amet.' + } + serializer = LongTextSerializer(data, self.long_text) + self.assertEquals(serializer.is_valid(), True) + self.assertEquals(data['content'], self.long_text.content) + class MetadataTests(TestCase): def test_empty(self): From de4604be0ab64da2d7da0a7054197278e566ced2 Mon Sep 17 00:00:00 2001 From: Jens Alm Date: Mon, 15 Oct 2012 11:47:56 +0200 Subject: [PATCH 3/5] Support for request-based queryset limits on ListModelMixin ListModelMixin uses the get_queryset from the MultipleObjectMixin. This method can be overridden on the View class to return a different queryset, but get_queryset doesn't accept a request parameter in. This commit adds the limit_list hook to override if you want to limit the queryset based on request-information such as the logged in user. --- rest_framework/mixins.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index 29153e182..2834c882e 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -32,8 +32,15 @@ class ListModelMixin(object): """ empty_error = u"Empty list and '%(class_name)s.allow_empty' is False." + def limit_list(self, request, queryset): + """ + Override this method to limit the queryset based on information in the request, such as the logged in user. + Should return the limited queryset, defaults to no limits. + """ + return queryset + def list(self, request, *args, **kwargs): - self.object_list = self.get_queryset() + self.object_list = self.limit_list(request, self.get_queryset()) # Default is to allow empty querysets. This can be altered by setting # `.allow_empty = False`, to raise 404 errors on empty querysets. From afbc9684f2108f6fd0ad4ef0ab4c5d19953c1561 Mon Sep 17 00:00:00 2001 From: Jens Alm Date: Mon, 15 Oct 2012 11:49:56 +0200 Subject: [PATCH 4/5] Revert "Support for request-based queryset limits on ListModelMixin" This reverts commit de4604be0ab64da2d7da0a7054197278e566ced2. --- rest_framework/mixins.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index 2834c882e..29153e182 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -32,15 +32,8 @@ class ListModelMixin(object): """ empty_error = u"Empty list and '%(class_name)s.allow_empty' is False." - def limit_list(self, request, queryset): - """ - Override this method to limit the queryset based on information in the request, such as the logged in user. - Should return the limited queryset, defaults to no limits. - """ - return queryset - def list(self, request, *args, **kwargs): - self.object_list = self.limit_list(request, self.get_queryset()) + self.object_list = self.get_queryset() # Default is to allow empty querysets. This can be altered by setting # `.allow_empty = False`, to raise 404 errors on empty querysets. From c94272650915eef368cdc5d157644884c3eecccb Mon Sep 17 00:00:00 2001 From: Jens Alm Date: Mon, 15 Oct 2012 13:46:44 +0200 Subject: [PATCH 5/5] Added docs, integer fields and refactored models.TextField to use CharField I realized that per the django forms, there is no need for a separate TextField, an unlimited CharField is perfectly good. Also added default field for the different IntegerField types --- docs/api-guide/fields.md | 17 +++++++++++++++++ rest_framework/serializers.py | 5 ++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index df54ea021..dc9ab0452 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -73,18 +73,35 @@ These fields represent basic datatypes, and support both reading and writing val ## BooleanField +A Boolean representation, corresponds to `django.db.models.fields.BooleanField`. + ## CharField +A text representation, optionally validates the text to be shorter than `max_length` and longer than `min_length`, corresponds to `django.db.models.fields.CharField` +or `django.db.models.fields.TextField`. + +**Signature:** `CharField([max_length=[, min_length=]])` + ## EmailField +A text representation, validates the text to be a valid e-mail adress. Corresponds to `django.db.models.fields.EmailField` + ## DateField +A date representation. Corresponds to `django.db.models.fields.DateField` + ## DateTimeField +A date and time representation. Corresponds to `django.db.models.fields.DateTimeField` + ## IntegerField +An integer representation. Corresponds to `django.db.models.fields.IntegerField`, `django.db.models.fields.SmallIntegerField`, `django.db.models.fields.PositiveIntegerField` and `django.db.models.fields.PositiveSmallIntegerField` + ## FloatField +A floating point representation. Corresponds to `django.db.models.fields.FloatField`. + --- # Relational Fields diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 5afbced29..13f8cde21 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -377,11 +377,14 @@ class ModelSerializer(Serializer): field_mapping = { models.FloatField: FloatField, models.IntegerField: IntegerField, + models.PositiveIntegerField: IntegerField, + models.SmallIntegerField: IntegerField, + models.PositiveSmallIntegerField: IntegerField, models.DateTimeField: DateTimeField, models.DateField: DateField, models.EmailField: EmailField, models.CharField: CharField, - models.TextField: TextField, + models.TextField: CharField, models.CommaSeparatedIntegerField: CharField, models.BooleanField: BooleanField, }