From cb5cc70cbac7531693594a416a0397db61dda94c Mon Sep 17 00:00:00 2001 From: Michael Elovskikh Date: Mon, 28 Jan 2013 18:01:44 +0600 Subject: Login page styles fix. Closes #618. Made with :cookie: --- rest_framework/templates/rest_framework/login.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'rest_framework') diff --git a/rest_framework/templates/rest_framework/login.html b/rest_framework/templates/rest_framework/login.html index 6e2bd8d4..e10ce20f 100644 --- a/rest_framework/templates/rest_framework/login.html +++ b/rest_framework/templates/rest_framework/login.html @@ -25,14 +25,14 @@
{% csrf_token %}
-
- +
+
-
- +
+
-- cgit v1.2.3 From a3a06d11cc39da55d34f99e272bf092a2dcd4c5c Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 28 Jan 2013 12:56:42 +0000 Subject: Ensure model field validation is performed for ModelSerializers with a custom restore_object method. Fixes #623. --- rest_framework/serializers.py | 30 ++++++++++++++++++++++++------ rest_framework/tests/serializer.py | 27 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) (limited to 'rest_framework') diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 6ecc7b45..0fed2c29 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -513,6 +513,22 @@ class ModelSerializer(Serializer): exclusions.remove(field_name) return exclusions + def full_clean(self, instance): + """ + Perform Django's full_clean, and populate the `errors` dictionary + if any validation errors occur. + + Note that we don't perform this inside the `.restore_object()` method, + so that subclasses can override `.restore_object()`, and still get + the full_clean validation checking. + """ + try: + instance.full_clean(exclude=self.get_validation_exclusions()) + except ValidationError, err: + self._errors = err.message_dict + return None + return instance + def restore_object(self, attrs, instance=None): """ Restore the model instance. @@ -544,14 +560,16 @@ class ModelSerializer(Serializer): else: instance = self.opts.model(**attrs) - try: - instance.full_clean(exclude=self.get_validation_exclusions()) - except ValidationError, err: - self._errors = err.message_dict - return None - return instance + def from_native(self, data, files): + """ + Override the default method to also include model field validation. + """ + instance = super(ModelSerializer, self).from_native(data, files) + if instance: + return self.full_clean(instance) + def save(self): """ Save the deserialized object and return it. diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index b4428ca3..48b4f1ab 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -54,6 +54,19 @@ class ActionItemSerializer(serializers.ModelSerializer): model = ActionItem +class ActionItemSerializerCustomRestore(serializers.ModelSerializer): + + class Meta: + model = ActionItem + + def restore_object(self, data, instance=None): + if instance is None: + return ActionItem(**data) + for key, val in data.items(): + setattr(instance, key, val) + return instance + + class PersonSerializer(serializers.ModelSerializer): info = serializers.Field(source='info') @@ -273,6 +286,20 @@ class ValidationTests(TestCase): self.assertEquals(serializer.is_valid(), False) self.assertEquals(serializer.errors, {'title': [u'Ensure this value has at most 200 characters (it has 201).']}) + def test_modelserializer_max_length_exceeded_with_custom_restore(self): + """ + When overriding ModelSerializer.restore_object, validation tests should still apply. + Regression test for #623. + + https://github.com/tomchristie/django-rest-framework/pull/623 + """ + data = { + 'title': 'x' * 201, + } + serializer = ActionItemSerializerCustomRestore(data=data) + self.assertEquals(serializer.is_valid(), False) + self.assertEquals(serializer.errors, {'title': [u'Ensure this value has at most 200 characters (it has 201).']}) + def test_default_modelfield_max_length_exceeded(self): data = { 'title': 'Testing "info" field...', -- cgit v1.2.3 From 85e6360792e1adbee1d457e25dc2d357c6d55adc Mon Sep 17 00:00:00 2001 From: Andrea de Marco Date: Mon, 28 Jan 2013 22:08:40 +0100 Subject: Update rest_framework/serializers.py --- rest_framework/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework') diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 0fed2c29..4fb802a7 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -469,7 +469,7 @@ class ModelSerializer(Serializer): kwargs['required'] = False kwargs['default'] = model_field.get_default() - if model_field.__class__ == models.TextField: + if issubclass(model_field.__class__, models.TextField): kwargs['widget'] = widgets.Textarea # TODO: TypedChoiceField? -- cgit v1.2.3 From fceacd830fcd3b67425dafd5b0e6dcc5b285b6ca Mon Sep 17 00:00:00 2001 From: Fernando Rocha Date: Tue, 29 Jan 2013 18:46:05 -0300 Subject: Fix processing of ManyToManyField when it is empty Signed-off-by: Fernando Rocha --- rest_framework/relations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework') diff --git a/rest_framework/relations.py b/rest_framework/relations.py index af63ceaa..dc0a73e6 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -148,7 +148,7 @@ class ManyRelatedMixin(object): value = data.getlist(self.source or field_name) except: # Non-form data - value = data.get(self.source or field_name) + value = data.get(self.source or field_name, []) else: if value == ['']: value = [] -- cgit v1.2.3 From 41364b3be0536a606d9b41d3792c2e562b860360 Mon Sep 17 00:00:00 2001 From: Fernando Rocha Date: Wed, 30 Jan 2013 09:09:17 -0300 Subject: Added regretion test for issue #632 Signed-off-by: Fernando Rocha --- rest_framework/tests/relations.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'rest_framework') diff --git a/rest_framework/tests/relations.py b/rest_framework/tests/relations.py index 91daea8a..edc85f9e 100644 --- a/rest_framework/tests/relations.py +++ b/rest_framework/tests/relations.py @@ -31,3 +31,17 @@ class FieldTests(TestCase): field = serializers.SlugRelatedField(queryset=NullModel.objects.all(), slug_field='pk') self.assertRaises(serializers.ValidationError, field.from_native, '') self.assertRaises(serializers.ValidationError, field.from_native, []) + + +class TestManyRelateMixin(TestCase): + def test_missing_many_to_many_related_field(self): + ''' + Regression test for #632 + + https://github.com/tomchristie/django-rest-framework/pull/632 + ''' + field = serializers.ManyRelatedField(read_only=False) + + into = {} + field.field_from_native({}, None, 'field_name', into) + self.assertEqual(into['field_name'], []) -- cgit v1.2.3