+
{{ request.method }} {{ request.get_full_path }}
diff --git a/rest_framework/templates/rest_framework/login_base.html b/rest_framework/templates/rest_framework/login_base.html
index a3e73b6b..be9a0072 100644
--- a/rest_framework/templates/rest_framework/login_base.html
+++ b/rest_framework/templates/rest_framework/login_base.html
@@ -4,8 +4,10 @@
{% block style %}
- {% block bootstrap_theme %}{% endblock %}
-
+ {% block bootstrap_theme %}
+
+
+ {% endblock %}
{% endblock %}
--
cgit v1.2.3
From 770ed3de2ef8339ec0b74f7eb522283718e01a3b Mon Sep 17 00:00:00 2001
From: Ryan Kaskel
Date: Sat, 18 May 2013 13:11:40 +0100
Subject: ToMany fields default to read-only if targeting ManyToManyField.
---
rest_framework/serializers.py | 17 ++++++++++
rest_framework/tests/relations_pk.py | 63 ++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+)
(limited to 'rest_framework')
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 7707de7a..75f1e1d0 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -587,11 +587,16 @@ class ModelSerializer(Serializer):
forward_rels += [field for field in opts.many_to_many if field.serialize]
for model_field in forward_rels:
+ has_user_through_model = False
+
if model_field.rel:
to_many = isinstance(model_field,
models.fields.related.ManyToManyField)
related_model = model_field.rel.to
+ if to_many and not model_field.rel.through._meta.auto_created:
+ has_user_through_model = True
+
if model_field.rel and nested:
if len(inspect.getargspec(self.get_nested_field).args) == 2:
warnings.warn(
@@ -620,6 +625,9 @@ class ModelSerializer(Serializer):
field = self.get_field(model_field)
if field:
+ if has_user_through_model:
+ field.read_only = True
+
ret[model_field.name] = field
# Deal with reverse relationships
@@ -637,6 +645,12 @@ class ModelSerializer(Serializer):
continue
related_model = relation.model
to_many = relation.field.rel.multiple
+ has_user_through_model = False
+ is_m2m = isinstance(relation.field,
+ models.fields.related.ManyToManyField)
+
+ if is_m2m and not relation.field.rel.through._meta.auto_created:
+ has_user_through_model = True
if nested:
field = self.get_nested_field(None, related_model, to_many)
@@ -644,6 +658,9 @@ class ModelSerializer(Serializer):
field = self.get_related_field(None, related_model, to_many)
if field:
+ if has_user_through_model:
+ field.read_only = True
+
ret[accessor_name] = field
# Add the `read_only` flag to any fields that have bee specified
diff --git a/rest_framework/tests/relations_pk.py b/rest_framework/tests/relations_pk.py
index 5ce8b567..02ffd264 100644
--- a/rest_framework/tests/relations_pk.py
+++ b/rest_framework/tests/relations_pk.py
@@ -1,4 +1,5 @@
from __future__ import unicode_literals
+from django.db import models
from django.test import TestCase
from rest_framework import serializers
from rest_framework.tests.models import ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource
@@ -124,6 +125,7 @@ class PKManyToManyTests(TestCase):
# Ensure source 4 is added, and everything else is as expected
queryset = ManyToManySource.objects.all()
serializer = ManyToManySourceSerializer(queryset, many=True)
+ self.assertFalse(serializer.fields['targets'].read_only)
expected = [
{'id': 1, 'name': 'source-1', 'targets': [1]},
{'id': 2, 'name': 'source-2', 'targets': [1, 2]},
@@ -135,6 +137,7 @@ class PKManyToManyTests(TestCase):
def test_reverse_many_to_many_create(self):
data = {'id': 4, 'name': 'target-4', 'sources': [1, 3]}
serializer = ManyToManyTargetSerializer(data=data)
+ self.assertFalse(serializer.fields['sources'].read_only)
self.assertTrue(serializer.is_valid())
obj = serializer.save()
self.assertEqual(serializer.data, data)
@@ -421,3 +424,63 @@ class PKNullableOneToOneTests(TestCase):
{'id': 2, 'name': 'target-2', 'nullable_source': 1},
]
self.assertEqual(serializer.data, expected)
+
+
+# The below models and tests ensure that serializer fields corresponding
+# to a ManyToManyField field with a user-specified ``through`` model are
+# set to read only
+
+
+class ManyToManyThroughTarget(models.Model):
+ name = models.CharField(max_length=100)
+
+
+class ManyToManyThrough(models.Model):
+ source = models.ForeignKey('ManyToManyThroughSource')
+ target = models.ForeignKey(ManyToManyThroughTarget)
+
+
+class ManyToManyThroughSource(models.Model):
+ name = models.CharField(max_length=100)
+ targets = models.ManyToManyField(ManyToManyThroughTarget,
+ related_name='sources',
+ through='ManyToManyThrough')
+
+
+class ManyToManyThroughTargetSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = ManyToManyThroughTarget
+ fields = ('id', 'name', 'sources')
+
+
+class ManyToManyThroughSourceSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = ManyToManyThroughSource
+ fields = ('id', 'name', 'targets')
+
+
+class PKManyToManyThroughTests(TestCase):
+ def setUp(self):
+ self.source = ManyToManyThroughSource.objects.create(
+ name='through-source-1')
+ self.target = ManyToManyThroughTarget.objects.create(
+ name='through-target-1')
+
+ def test_many_to_many_create(self):
+ data = {'id': 2, 'name': 'source-2', 'targets': [self.target.pk]}
+ serializer = ManyToManyThroughSourceSerializer(data=data)
+ self.assertTrue(serializer.fields['targets'].read_only)
+ self.assertTrue(serializer.is_valid())
+ obj = serializer.save()
+ self.assertEqual(obj.name, 'source-2')
+ self.assertEqual(obj.targets.count(), 0)
+
+ def test_many_to_many_reverse_create(self):
+ data = {'id': 2, 'name': 'target-2', 'sources': [self.source.pk]}
+ serializer = ManyToManyThroughTargetSerializer(data=data)
+ self.assertTrue(serializer.fields['sources'].read_only)
+ self.assertTrue(serializer.is_valid())
+ serializer.save()
+ obj = serializer.save()
+ self.assertEqual(obj.name, 'target-2')
+ self.assertEqual(obj.sources.count(), 0)
--
cgit v1.2.3
From 392c8556aed41df2120623fe1c891610bb111100 Mon Sep 17 00:00:00 2001
From: Pablo Recio
Date: Sat, 18 May 2013 15:01:58 +0200
Subject: Display an empty label into related fields if it isn't required
---
rest_framework/relations.py | 8 +++++-
rest_framework/tests/serializer.py | 57 ++++++++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+), 1 deletion(-)
(limited to 'rest_framework')
diff --git a/rest_framework/relations.py b/rest_framework/relations.py
index 884b954c..3aaf6648 100644
--- a/rest_framework/relations.py
+++ b/rest_framework/relations.py
@@ -8,6 +8,7 @@ from __future__ import unicode_literals
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.core.urlresolvers import resolve, get_script_prefix, NoReverseMatch
from django import forms
+from django.db.models.fields import BLANK_CHOICE_DASH
from django.forms import widgets
from django.forms.models import ModelChoiceIterator
from django.utils.translation import ugettext_lazy as _
@@ -47,7 +48,7 @@ class RelatedField(WritableField):
DeprecationWarning, stacklevel=2)
kwargs['required'] = not kwargs.pop('null')
- self.queryset = kwargs.pop('queryset', None)
+ queryset = kwargs.pop('queryset', None)
self.many = kwargs.pop('many', self.many)
if self.many:
self.widget = self.many_widget
@@ -56,6 +57,11 @@ class RelatedField(WritableField):
kwargs['read_only'] = kwargs.pop('read_only', self.read_only)
super(RelatedField, self).__init__(*args, **kwargs)
+ if not self.required:
+ self.empty_label = BLANK_CHOICE_DASH[0][1]
+
+ self.queryset = queryset
+
def initialize(self, parent, field_name):
super(RelatedField, self).initialize(parent, field_name)
if self.queryset is None and not self.read_only:
diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py
index d0a8570c..69b33209 100644
--- a/rest_framework/tests/serializer.py
+++ b/rest_framework/tests/serializer.py
@@ -1117,6 +1117,63 @@ class SerializerChoiceFields(TestCase):
)
+# Regression tests for #675
+class Ticket(models.Model):
+ assigned = models.ForeignKey(
+ Person, related_name='assigned_tickets')
+ reviewer = models.ForeignKey(
+ Person, blank=True, null=True, related_name='reviewed_tickets')
+
+
+class SerializerRelatedChoicesTest(TestCase):
+
+ def setUp(self):
+ super(SerializerRelatedChoicesTest, self).setUp()
+
+ class RelatedChoicesSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Ticket
+ fields = ('assigned', 'reviewer')
+
+ self.related_fields_serializer = RelatedChoicesSerializer
+
+ def test_empty_queryset_required(self):
+ serializer = self.related_fields_serializer()
+ self.assertEqual(serializer.fields['assigned'].queryset.count(), 0)
+ self.assertEqual(
+ [x for x in serializer.fields['assigned'].widget.choices],
+ []
+ )
+
+ def test_empty_queryset_not_required(self):
+ serializer = self.related_fields_serializer()
+ self.assertEqual(serializer.fields['reviewer'].queryset.count(), 0)
+ self.assertEqual(
+ [x for x in serializer.fields['reviewer'].widget.choices],
+ [(u'', u'---------')]
+ )
+
+ def test_with_some_persons_required(self):
+ Person.objects.create(name="Lionel Messi")
+ Person.objects.create(name="Xavi Hernandez")
+ serializer = self.related_fields_serializer()
+ self.assertEqual(serializer.fields['assigned'].queryset.count(), 2)
+ self.assertEqual(
+ [x for x in serializer.fields['assigned'].widget.choices],
+ [(1, u'Person object - 1'), (2, u'Person object - 2')]
+ )
+
+ def test_with_some_persons_not_required(self):
+ Person.objects.create(name="Lionel Messi")
+ Person.objects.create(name="Xavi Hernandez")
+ serializer = self.related_fields_serializer()
+ self.assertEqual(serializer.fields['reviewer'].queryset.count(), 2)
+ self.assertEqual(
+ [x for x in serializer.fields['reviewer'].widget.choices],
+ [(u'', u'---------'), (1, u'Person object - 1'), (2, u'Person object - 2')]
+ )
+
+
class DepthTest(TestCase):
def test_implicit_nesting(self):
--
cgit v1.2.3
From a71acc76d8ede28ad9c5f9fd0fc129f6321c9231 Mon Sep 17 00:00:00 2001
From: Stephan Groß
Date: Sat, 18 May 2013 15:12:54 +0200
Subject: Fix for #710
---
rest_framework/serializers.py | 16 ++++++++
rest_framework/tests/serializer.py | 84 +++++++++++++++++++++++++++++++++++++-
2 files changed, 99 insertions(+), 1 deletion(-)
(limited to 'rest_framework')
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 500bb306..1b451f2d 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -723,6 +723,22 @@ class ModelSerializer(Serializer):
kwargs['choices'] = model_field.flatchoices
return ChoiceField(**kwargs)
+ attribute_dict = {
+ models.CharField: ['max_length'],
+ models.CommaSeparatedIntegerField: ['max_length'],
+ models.DecimalField: ['max_digits', 'decimal_places'],
+ models.EmailField: ['max_length'],
+ models.FileField: ['max_length'],
+ models.ImageField: ['max_length'],
+ models.SlugField: ['max_length'],
+ models.URLField: ['max_length'],
+ }
+
+ if model_field.__class__ in attribute_dict:
+ attributes = attribute_dict[model_field.__class__]
+ for attribute in attributes:
+ kwargs.update({attribute: model_field.__getattribute__(attribute)})
+
try:
return self.field_mapping[model_field.__class__](**kwargs)
except KeyError:
diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py
index d0a8570c..73d6a15b 100644
--- a/rest_framework/tests/serializer.py
+++ b/rest_framework/tests/serializer.py
@@ -6,7 +6,7 @@ from django.test import TestCase
from rest_framework import serializers
from rest_framework.tests.models import (HasPositiveIntegerAsChoice, Album, ActionItem, Anchor, BasicModel,
BlankFieldModel, BlogPost, BlogPostComment, Book, CallableDefaultValueModel, DefaultValueModel,
- ManyToManyModel, Person, ReadOnlyManyToManyModel, Photo)
+ ManyToManyModel, Person, ReadOnlyManyToManyModel, Photo, RESTFrameworkModel)
import datetime
import pickle
@@ -1242,3 +1242,85 @@ class DeserializeListTestCase(TestCase):
self.assertFalse(serializer.is_valid())
expected = [{}, {'email': ['This field is required.']}, {}]
self.assertEqual(serializer.errors, expected)
+
+
+class AttributeMappingOnAutogeneratedFieldsTests(TestCase):
+
+ def setUp(self):
+ class AMOAFModel(RESTFrameworkModel):
+ char_field = models.CharField(max_length=1024, blank=True)
+ comma_separated_integer_field = models.CommaSeparatedIntegerField(max_length=1024, blank=True)
+ decimal_field = models.DecimalField(max_digits=64, decimal_places=32, blank=True)
+ email_field = models.EmailField(max_length=1024, blank=True)
+ file_field = models.FileField(max_length=1024, blank=True)
+ image_field = models.ImageField(max_length=1024, blank=True)
+ slug_field = models.SlugField(max_length=1024, blank=True)
+ url_field = models.URLField(max_length=1024, blank=True)
+
+ class AMOAFSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = AMOAFModel
+
+ self.serializer_class = AMOAFSerializer
+ self.objects = AMOAFModel.objects
+ self.fields_attributes = {
+ 'char_field': [
+ ('max_length', 1024),
+ ],
+ 'comma_separated_integer_field': [
+ ('max_length', 1024),
+ ],
+ 'decimal_field': [
+ ('max_digits', 64),
+ ('decimal_places', 32),
+ ],
+ 'email_field': [
+ ('max_length', 1024),
+ ],
+ 'file_field': [
+ ('max_length', 1024),
+ ],
+ 'image_field': [
+ ('max_length', 1024),
+ ],
+ 'slug_field': [
+ ('max_length', 1024),
+ ],
+ 'url_field': [
+ ('max_length', 1024),
+ ],
+ }
+
+ def field_test(self, field):
+ serializer = self.serializer_class(data={})
+ self.assertEqual(serializer.is_valid(), True)
+
+ for attribute in self.fields_attributes[field]:
+ self.assertEqual(
+ getattr(serializer.fields[field], attribute[0]),
+ attribute[1]
+ )
+
+ def test_char_field(self):
+ self.field_test('char_field')
+
+ def test_comma_separated_integer_field(self):
+ self.field_test('comma_separated_integer_field')
+
+ def test_decimal_field(self):
+ self.field_test('decimal_field')
+
+ def test_email_field(self):
+ self.field_test('email_field')
+
+ def test_file_field(self):
+ self.field_test('file_field')
+
+ def test_image_field(self):
+ self.field_test('image_field')
+
+ def test_slug_field(self):
+ self.field_test('slug_field')
+
+ def test_url_field(self):
+ self.field_test('url_field')
--
cgit v1.2.3
From 208bd991dacb6c2edc9fc820717354c579c2e6d6 Mon Sep 17 00:00:00 2001
From: Craig de Stigter
Date: Sat, 18 May 2013 15:23:43 +0200
Subject: when source='*' on a nested serializer, expand fields into outer
serializer when writing. fixes #765
---
rest_framework/serializers.py | 34 +++++++++++++++++++---------------
rest_framework/tests/serializer.py | 22 ++++++++++++++++++++++
2 files changed, 41 insertions(+), 15 deletions(-)
(limited to 'rest_framework')
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 7707de7a..ef099e57 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -378,23 +378,27 @@ class BaseSerializer(WritableField):
# Set the serializer object if it exists
obj = getattr(self.parent.object, field_name) if self.parent.object else None
- if value in (None, ''):
- into[(self.source or field_name)] = None
+ if self.source == '*':
+ if value:
+ into.update(value)
else:
- kwargs = {
- 'instance': obj,
- 'data': value,
- 'context': self.context,
- 'partial': self.partial,
- 'many': self.many
- }
- serializer = self.__class__(**kwargs)
-
- if serializer.is_valid():
- into[self.source or field_name] = serializer.object
+ if value in (None, ''):
+ into[(self.source or field_name)] = None
else:
- # Propagate errors up to our parent
- raise NestedValidationError(serializer.errors)
+ kwargs = {
+ 'instance': obj,
+ 'data': value,
+ 'context': self.context,
+ 'partial': self.partial,
+ 'many': self.many
+ }
+ serializer = self.__class__(**kwargs)
+
+ if serializer.is_valid():
+ into[self.source or field_name] = serializer.object
+ else:
+ # Propagate errors up to our parent
+ raise NestedValidationError(serializer.errors)
def get_identity(self, data):
"""
diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py
index 34acbaab..116459e0 100644
--- a/rest_framework/tests/serializer.py
+++ b/rest_framework/tests/serializer.py
@@ -78,6 +78,17 @@ class PersonSerializer(serializers.ModelSerializer):
read_only_fields = ('age',)
+class NestedSerializer(serializers.Serializer):
+ info = serializers.Field()
+
+
+class ModelSerializerWithNestedSerializer(serializers.ModelSerializer):
+ nested = NestedSerializer(source='*')
+
+ class Meta:
+ model = Person
+
+
class PersonSerializerInvalidReadOnly(serializers.ModelSerializer):
"""
Testing for #652.
@@ -369,6 +380,17 @@ class ValidationTests(TestCase):
except:
self.fail('Wrong exception type thrown.')
+ def test_writable_star_source_on_nested_serializer(self):
+ """
+ Assert that a nested serializer instantiated with source='*' correctly
+ expands the data into the outer serializer.
+ """
+ serializer = ModelSerializerWithNestedSerializer(data={
+ 'name': 'marko',
+ 'nested': {'info': 'hi'}},
+ )
+ self.assertEqual(serializer.is_valid(), True)
+
class CustomValidationTests(TestCase):
class CommentSerializerWithFieldValidator(CommentSerializer):
--
cgit v1.2.3
From e6409bbc836cbe61be7f525900f5bc0616f5c225 Mon Sep 17 00:00:00 2001
From: Stephan Groß
Date: Sat, 18 May 2013 15:48:36 +0200
Subject: Temp commit for branch change ;-)
---
rest_framework/tests/fields.py | 61 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
(limited to 'rest_framework')
diff --git a/rest_framework/tests/fields.py b/rest_framework/tests/fields.py
index 6b1cdfc7..cb5b05dc 100644
--- a/rest_framework/tests/fields.py
+++ b/rest_framework/tests/fields.py
@@ -10,6 +10,7 @@ from django.test import TestCase
from django.core import validators
from rest_framework import serializers
from rest_framework.serializers import Serializer
+from rest_framework.tests.models import RESTFrameworkModel
class TimestampedModel(models.Model):
@@ -685,3 +686,63 @@ class ChoiceFieldTests(TestCase):
"""
f = serializers.ChoiceField(required=False, choices=self.SAMPLE_CHOICES)
self.assertEqual(f.choices, models.fields.BLANK_CHOICE_DASH + self.SAMPLE_CHOICES)
+
+
+class SlugFieldTests(TestCase):
+ """
+ Tests for SlugField attribute values
+ """
+
+ def test_default_value(self):
+ class SlugFieldModel(RESTFrameworkModel):
+ slug_field = models.SlugField(blank=True)
+
+ class SlugFieldSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = SlugFieldModel
+
+ serializer = SlugFieldSerializer(data={})
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(getattr(serializer.fields['slug_field'], 'max_length'), 50)
+
+ def test_given_value(self):
+ class SlugFieldModel(RESTFrameworkModel):
+ slug_field = models.SlugField(max_length=84, blank=True)
+
+ class SlugFieldSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = SlugFieldModel
+
+ serializer = SlugFieldSerializer(data={})
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(getattr(serializer.fields['slug_field'], 'max_length'), 84)
+
+
+class URLFieldTests(TestCase):
+ """
+ Tests for URLField attribute values
+ """
+
+ def test_default_value(self):
+ class URLFieldModel(RESTFrameworkModel):
+ url_field = models.URLField(blank=True)
+
+ class URLFieldSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = URLFieldModel
+
+ serializer = URLFieldSerializer(data={})
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 200)
+
+ def test_given_value(self):
+ class URLFieldModel(RESTFrameworkModel):
+ url_field = models.URLField(max_length=128, blank=True)
+
+ class URLFieldSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = URLFieldModel
+
+ serializer = URLFieldSerializer(data={})
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 128)
\ No newline at end of file
--
cgit v1.2.3
From eb9fdd04fceac322af92bd196293390270653ccd Mon Sep 17 00:00:00 2001
From: Stephan Groß
Date: Sat, 18 May 2013 15:50:12 +0200
Subject: Remove unused var
---
rest_framework/tests/serializer.py | 1 -
1 file changed, 1 deletion(-)
(limited to 'rest_framework')
diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py
index 73d6a15b..8b487b54 100644
--- a/rest_framework/tests/serializer.py
+++ b/rest_framework/tests/serializer.py
@@ -1262,7 +1262,6 @@ class AttributeMappingOnAutogeneratedFieldsTests(TestCase):
model = AMOAFModel
self.serializer_class = AMOAFSerializer
- self.objects = AMOAFModel.objects
self.fields_attributes = {
'char_field': [
('max_length', 1024),
--
cgit v1.2.3
From 80a2600891aab2211c8c4bf3ce78e3c1d5c6de72 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Sat, 18 May 2013 14:55:48 +0100
Subject: Styling tweaks
---
rest_framework/static/rest_framework/css/bootstrap-tweaks.css | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'rest_framework')
diff --git a/rest_framework/static/rest_framework/css/bootstrap-tweaks.css b/rest_framework/static/rest_framework/css/bootstrap-tweaks.css
index 69e1e70d..9b520156 100644
--- a/rest_framework/static/rest_framework/css/bootstrap-tweaks.css
+++ b/rest_framework/static/rest_framework/css/bootstrap-tweaks.css
@@ -37,7 +37,7 @@ a single block in the template.
border-radius: 0px;
}
-.navbar .navbar-inner .nav li, .navbar .navbar-inner .nav li a, .navbar .navbar-inner .brand{
+.navbar .navbar-inner .nav li, .navbar .navbar-inner .nav li a, .navbar .navbar-inner .brand:hover{
color: white;
}
@@ -178,4 +178,4 @@ body a:hover{
.request-info {
clear:both;
-}
\ No newline at end of file
+}
--
cgit v1.2.3
From b7176065a9aafb3d560f9e8c2e420bd4cc5841dc Mon Sep 17 00:00:00 2001
From: Stephan Groß
Date: Sat, 18 May 2013 16:06:30 +0200
Subject: Update getattr
---
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 1b451f2d..338803fe 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -737,7 +737,7 @@ class ModelSerializer(Serializer):
if model_field.__class__ in attribute_dict:
attributes = attribute_dict[model_field.__class__]
for attribute in attributes:
- kwargs.update({attribute: model_field.__getattribute__(attribute)})
+ kwargs.update({attribute: getattr(model_field, attribute)})
try:
return self.field_mapping[model_field.__class__](**kwargs)
--
cgit v1.2.3
From aeba5bed05e37344caf15adff180fc48404d992d Mon Sep 17 00:00:00 2001
From: Andy McKay
Date: Sat, 18 May 2013 07:09:24 -0700
Subject: startswith can take a tuple
---
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 884b954c..c7256587 100644
--- a/rest_framework/relations.py
+++ b/rest_framework/relations.py
@@ -442,7 +442,7 @@ class HyperlinkedRelatedField(RelatedField):
raise Exception('Writable related fields must include a `queryset` argument')
try:
- http_prefix = value.startswith('http:') or value.startswith('https:')
+ http_prefix = value.startswith(('http:', 'https:'))
except AttributeError:
msg = self.error_messages['incorrect_type']
raise ValidationError(msg % type(value).__name__)
--
cgit v1.2.3
From 7dca0e68591569c2838e383f15f690f5891509b1 Mon Sep 17 00:00:00 2001
From: Pablo Recio
Date: Sat, 18 May 2013 16:12:48 +0200
Subject: Removed unicode literals
---
rest_framework/tests/serializer.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'rest_framework')
diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py
index 50b06582..96f18451 100644
--- a/rest_framework/tests/serializer.py
+++ b/rest_framework/tests/serializer.py
@@ -1172,7 +1172,7 @@ class SerializerRelatedChoicesTest(TestCase):
self.assertEqual(serializer.fields['reviewer'].queryset.count(), 0)
self.assertEqual(
[x for x in serializer.fields['reviewer'].widget.choices],
- [(u'', u'---------')]
+ [('', '---------')]
)
def test_with_some_persons_required(self):
@@ -1182,7 +1182,7 @@ class SerializerRelatedChoicesTest(TestCase):
self.assertEqual(serializer.fields['assigned'].queryset.count(), 2)
self.assertEqual(
[x for x in serializer.fields['assigned'].widget.choices],
- [(1, u'Person object - 1'), (2, u'Person object - 2')]
+ [(1, 'Person object - 1'), (2, 'Person object - 2')]
)
def test_with_some_persons_not_required(self):
@@ -1192,7 +1192,7 @@ class SerializerRelatedChoicesTest(TestCase):
self.assertEqual(serializer.fields['reviewer'].queryset.count(), 2)
self.assertEqual(
[x for x in serializer.fields['reviewer'].widget.choices],
- [(u'', u'---------'), (1, u'Person object - 1'), (2, u'Person object - 2')]
+ [('', '---------'), (1, 'Person object - 1'), (2, 'Person object - 2')]
)
--
cgit v1.2.3
From 9f9cb97d6538e320a0740749b200d418d9d52040 Mon Sep 17 00:00:00 2001
From: Stephan Groß
Date: Sat, 18 May 2013 16:24:54 +0200
Subject: Add TestCases for default field values
---
rest_framework/fields.py | 2 -
rest_framework/tests/fields.py | 99 ++++++++++++++++++++++++++++++++++--------
2 files changed, 81 insertions(+), 20 deletions(-)
(limited to 'rest_framework')
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index 491aa7ed..fc14184c 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -383,7 +383,6 @@ class URLField(CharField):
type_name = 'URLField'
def __init__(self, **kwargs):
- kwargs['max_length'] = kwargs.get('max_length', 200)
kwargs['validators'] = [validators.URLValidator()]
super(URLField, self).__init__(**kwargs)
@@ -392,7 +391,6 @@ class SlugField(CharField):
type_name = 'SlugField'
def __init__(self, *args, **kwargs):
- kwargs['max_length'] = kwargs.get('max_length', 50)
super(SlugField, self).__init__(*args, **kwargs)
diff --git a/rest_framework/tests/fields.py b/rest_framework/tests/fields.py
index cb5b05dc..d82f6b23 100644
--- a/rest_framework/tests/fields.py
+++ b/rest_framework/tests/fields.py
@@ -688,61 +688,124 @@ class ChoiceFieldTests(TestCase):
self.assertEqual(f.choices, models.fields.BLANK_CHOICE_DASH + self.SAMPLE_CHOICES)
+class EmailFieldTests(TestCase):
+ """
+ Tests for EmailField attribute values
+ """
+
+ class EmailFieldModel(RESTFrameworkModel):
+ email_field = models.EmailField(blank=True)
+
+ class EmailFieldWithGivenMaxLengthModel(RESTFrameworkModel):
+ email_field = models.EmailField(max_length=150, blank=True)
+
+ def test_default_model_value(self):
+ class EmailFieldSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = self.EmailFieldModel
+
+ serializer = EmailFieldSerializer(data={})
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(getattr(serializer.fields['email_field'], 'max_length'), 75)
+
+ def test_given_model_value(self):
+ class EmailFieldSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = self.EmailFieldWithGivenMaxLengthModel
+
+ serializer = EmailFieldSerializer(data={})
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(getattr(serializer.fields['email_field'], 'max_length'), 150)
+
+ def test_given_serializer_value(self):
+ class EmailFieldSerializer(serializers.ModelSerializer):
+ email_field = serializers.EmailField(source='email_field', max_length=20, required=False)
+
+ class Meta:
+ model = self.EmailFieldModel
+
+ serializer = EmailFieldSerializer(data={})
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(getattr(serializer.fields['email_field'], 'max_length'), 20)
+
+
class SlugFieldTests(TestCase):
"""
Tests for SlugField attribute values
"""
- def test_default_value(self):
- class SlugFieldModel(RESTFrameworkModel):
- slug_field = models.SlugField(blank=True)
+ class SlugFieldModel(RESTFrameworkModel):
+ slug_field = models.SlugField(blank=True)
+
+ class SlugFieldWithGivenMaxLengthModel(RESTFrameworkModel):
+ slug_field = models.SlugField(max_length=84, blank=True)
+ def test_default_model_value(self):
class SlugFieldSerializer(serializers.ModelSerializer):
class Meta:
- model = SlugFieldModel
+ model = self.SlugFieldModel
serializer = SlugFieldSerializer(data={})
self.assertEqual(serializer.is_valid(), True)
self.assertEqual(getattr(serializer.fields['slug_field'], 'max_length'), 50)
- def test_given_value(self):
- class SlugFieldModel(RESTFrameworkModel):
- slug_field = models.SlugField(max_length=84, blank=True)
-
+ def test_given_model_value(self):
class SlugFieldSerializer(serializers.ModelSerializer):
class Meta:
- model = SlugFieldModel
+ model = self.SlugFieldWithGivenMaxLengthModel
serializer = SlugFieldSerializer(data={})
self.assertEqual(serializer.is_valid(), True)
self.assertEqual(getattr(serializer.fields['slug_field'], 'max_length'), 84)
+ def test_given_serializer_value(self):
+ class SlugFieldSerializer(serializers.ModelSerializer):
+ slug_field = serializers.SlugField(source='slug_field', max_length=20, required=False)
+
+ class Meta:
+ model = self.SlugFieldModel
+
+ serializer = SlugFieldSerializer(data={})
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(getattr(serializer.fields['slug_field'], 'max_length'), 20)
+
class URLFieldTests(TestCase):
"""
Tests for URLField attribute values
"""
- def test_default_value(self):
- class URLFieldModel(RESTFrameworkModel):
- url_field = models.URLField(blank=True)
+ class URLFieldModel(RESTFrameworkModel):
+ url_field = models.URLField(blank=True)
+
+ class URLFieldWithGivenMaxLengthModel(RESTFrameworkModel):
+ url_field = models.URLField(max_length=128, blank=True)
+ def test_default_model_value(self):
class URLFieldSerializer(serializers.ModelSerializer):
class Meta:
- model = URLFieldModel
+ model = self.URLFieldModel
serializer = URLFieldSerializer(data={})
self.assertEqual(serializer.is_valid(), True)
self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 200)
- def test_given_value(self):
- class URLFieldModel(RESTFrameworkModel):
- url_field = models.URLField(max_length=128, blank=True)
+ def test_given_model_value(self):
+ class URLFieldSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = self.URLFieldWithGivenMaxLengthModel
+
+ serializer = URLFieldSerializer(data={})
+ self.assertEqual(serializer.is_valid(), True)
+ self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 128)
+ def test_given_serializer_value(self):
class URLFieldSerializer(serializers.ModelSerializer):
+ url_field = serializers.URLField(source='url_field', max_length=20, required=False)
+
class Meta:
- model = URLFieldModel
+ model = self.URLFieldWithGivenMaxLengthModel
serializer = URLFieldSerializer(data={})
self.assertEqual(serializer.is_valid(), True)
- self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 128)
\ No newline at end of file
+ self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 20)
\ No newline at end of file
--
cgit v1.2.3
From 5f8d353f0b4e0938866a1e954bbd762f383d893b Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Sat, 18 May 2013 15:25:49 +0100
Subject: Rename has_user_through_model -> has_through_model
---
rest_framework/serializers.py | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
(limited to 'rest_framework')
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 3087d4e6..ff5eb873 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -591,7 +591,7 @@ class ModelSerializer(Serializer):
forward_rels += [field for field in opts.many_to_many if field.serialize]
for model_field in forward_rels:
- has_user_through_model = False
+ has_through_model = False
if model_field.rel:
to_many = isinstance(model_field,
@@ -599,7 +599,7 @@ class ModelSerializer(Serializer):
related_model = model_field.rel.to
if to_many and not model_field.rel.through._meta.auto_created:
- has_user_through_model = True
+ has_through_model = True
if model_field.rel and nested:
if len(inspect.getargspec(self.get_nested_field).args) == 2:
@@ -629,7 +629,7 @@ class ModelSerializer(Serializer):
field = self.get_field(model_field)
if field:
- if has_user_through_model:
+ if has_through_model:
field.read_only = True
ret[model_field.name] = field
@@ -649,12 +649,12 @@ class ModelSerializer(Serializer):
continue
related_model = relation.model
to_many = relation.field.rel.multiple
- has_user_through_model = False
+ has_through_model = False
is_m2m = isinstance(relation.field,
models.fields.related.ManyToManyField)
if is_m2m and not relation.field.rel.through._meta.auto_created:
- has_user_through_model = True
+ has_through_model = True
if nested:
field = self.get_nested_field(None, related_model, to_many)
@@ -662,7 +662,7 @@ class ModelSerializer(Serializer):
field = self.get_related_field(None, related_model, to_many)
if field:
- if has_user_through_model:
+ if has_through_model:
field.read_only = True
ret[accessor_name] = field
--
cgit v1.2.3
From aeea32030b53eb73547696783cc6eb0d3e14f156 Mon Sep 17 00:00:00 2001
From: Stephan Groß
Date: Sat, 18 May 2013 16:27:11 +0200
Subject: Add newline
---
rest_framework/tests/fields.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'rest_framework')
diff --git a/rest_framework/tests/fields.py b/rest_framework/tests/fields.py
index d82f6b23..109fd01f 100644
--- a/rest_framework/tests/fields.py
+++ b/rest_framework/tests/fields.py
@@ -808,4 +808,5 @@ class URLFieldTests(TestCase):
serializer = URLFieldSerializer(data={})
self.assertEqual(serializer.is_valid(), True)
- self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 20)
\ No newline at end of file
+ self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 20
+
\ No newline at end of file
--
cgit v1.2.3
From 6714b755f4938e998907e3d949c832f77a76fadc Mon Sep 17 00:00:00 2001
From: Stephan Groß
Date: Sat, 18 May 2013 16:32:31 +0200
Subject: Fix missing para..
---
rest_framework/tests/fields.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
(limited to 'rest_framework')
diff --git a/rest_framework/tests/fields.py b/rest_framework/tests/fields.py
index 109fd01f..dad69975 100644
--- a/rest_framework/tests/fields.py
+++ b/rest_framework/tests/fields.py
@@ -808,5 +808,4 @@ class URLFieldTests(TestCase):
serializer = URLFieldSerializer(data={})
self.assertEqual(serializer.is_valid(), True)
- self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 20
-
\ No newline at end of file
+ self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 20)
--
cgit v1.2.3