mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-24 08:14:16 +03:00
Adding BLANK_CHOICE_DASH
as a choice if the model's field isn't required
This commit is contained in:
parent
de5cc8de42
commit
ab8bd566f9
|
@ -15,6 +15,7 @@ import warnings
|
|||
from django.core import validators
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.conf import settings
|
||||
from django.db.models.fields import BLANK_CHOICE_DASH
|
||||
from django import forms
|
||||
from django.forms import widgets
|
||||
from django.utils.encoding import is_protected_type
|
||||
|
@ -402,6 +403,8 @@ class ChoiceField(WritableField):
|
|||
def __init__(self, choices=(), *args, **kwargs):
|
||||
super(ChoiceField, self).__init__(*args, **kwargs)
|
||||
self.choices = choices
|
||||
if not self.required:
|
||||
self.choices = BLANK_CHOICE_DASH + self.choices
|
||||
|
||||
def _get_choices(self):
|
||||
return self._choices
|
||||
|
|
|
@ -646,3 +646,29 @@ class DecimalFieldTest(TestCase):
|
|||
|
||||
self.assertFalse(s.is_valid())
|
||||
self.assertEqual(s.errors, {'decimal_field': ['Ensure that there are no more than 4 digits in total.']})
|
||||
|
||||
|
||||
class ChoiceFieldTests(TestCase):
|
||||
"""
|
||||
Tests for the ChoiceField options generator
|
||||
"""
|
||||
|
||||
SAMPLE_CHOICES = [
|
||||
('red', 'Red'),
|
||||
('green', 'Green'),
|
||||
('blue', 'Blue'),
|
||||
]
|
||||
|
||||
def test_choices_required(self):
|
||||
"""
|
||||
Make sure proper choices are rendered if field is required
|
||||
"""
|
||||
f = serializers.ChoiceField(required=True, choices=self.SAMPLE_CHOICES)
|
||||
self.assertEqual(f.choices, self.SAMPLE_CHOICES)
|
||||
|
||||
def test_choices_not_required(self):
|
||||
"""
|
||||
Make sure proper choices (plus blank) are rendered if the field isn't required
|
||||
"""
|
||||
f = serializers.ChoiceField(required=False, choices=self.SAMPLE_CHOICES)
|
||||
self.assertEqual(f.choices, models.fields.BLANK_CHOICE_DASH + self.SAMPLE_CHOICES)
|
||||
|
|
|
@ -117,6 +117,32 @@ class OptionalRelationModel(RESTFrameworkModel):
|
|||
other = models.ForeignKey('OptionalRelationModel', blank=True, null=True)
|
||||
|
||||
|
||||
# Model for issue #725
|
||||
class SeveralChoicesModel(RESTFrameworkModel):
|
||||
color = models.CharField(
|
||||
max_length=10,
|
||||
choices=[('red', 'Red'), ('green', 'Green'), ('blue', 'Blue')],
|
||||
blank=False
|
||||
)
|
||||
drink = models.CharField(
|
||||
max_length=10,
|
||||
choices=[('beer', 'Beer'), ('wine', 'Wine'), ('cider', 'Cider')],
|
||||
blank=False,
|
||||
default='beer'
|
||||
)
|
||||
os = models.CharField(
|
||||
max_length=10,
|
||||
choices=[('linux', 'Linux'), ('osx', 'OSX'), ('windows', 'Windows')],
|
||||
blank=True
|
||||
)
|
||||
music_genre = models.CharField(
|
||||
max_length=10,
|
||||
choices=[('rock', 'Rock'), ('metal', 'Metal'), ('grunge', 'Grunge')],
|
||||
blank=True,
|
||||
default='metal'
|
||||
)
|
||||
|
||||
|
||||
# Model for RegexField
|
||||
class Book(RESTFrameworkModel):
|
||||
isbn = models.CharField(max_length=13)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from __future__ import unicode_literals
|
||||
from django.db.models.fields import BLANK_CHOICE_DASH
|
||||
from django.utils.datastructures import MultiValueDict
|
||||
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, SeveralChoicesModel)
|
||||
import datetime
|
||||
import pickle
|
||||
|
||||
|
@ -1018,6 +1019,48 @@ class SerializerPickleTests(TestCase):
|
|||
repr(pickle.loads(pickle.dumps(data, 0)))
|
||||
|
||||
|
||||
# test for issue #725
|
||||
class SerializerChoiceFields(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(SerializerChoiceFields, self).setUp()
|
||||
|
||||
class SeveralChoicesSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = SeveralChoicesModel
|
||||
fields = ('color', 'drink', 'os', 'music_genre')
|
||||
|
||||
self.several_choices_serializer = SeveralChoicesSerializer
|
||||
|
||||
def test_choices_blank_false_not_default(self):
|
||||
serializer = self.several_choices_serializer()
|
||||
self.assertEqual(
|
||||
serializer.fields['color'].choices,
|
||||
[('red', 'Red'), ('green', 'Green'), ('blue', 'Blue')]
|
||||
)
|
||||
|
||||
def test_choices_blank_false_with_default(self):
|
||||
serializer = self.several_choices_serializer()
|
||||
self.assertEqual(
|
||||
serializer.fields['drink'].choices,
|
||||
[('beer', 'Beer'), ('wine', 'Wine'), ('cider', 'Cider')]
|
||||
)
|
||||
|
||||
def test_choices_blank_true_not_default(self):
|
||||
serializer = self.several_choices_serializer()
|
||||
self.assertEqual(
|
||||
serializer.fields['os'].choices,
|
||||
BLANK_CHOICE_DASH + [('linux', 'Linux'), ('osx', 'OSX'), ('windows', 'Windows')]
|
||||
)
|
||||
|
||||
def test_choices_blank_true_with_default(self):
|
||||
serializer = self.several_choices_serializer()
|
||||
self.assertEqual(
|
||||
serializer.fields['music_genre'].choices,
|
||||
BLANK_CHOICE_DASH + [('rock', 'Rock'), ('metal', 'Metal'), ('grunge', 'Grunge')]
|
||||
)
|
||||
|
||||
|
||||
class DepthTest(TestCase):
|
||||
def test_implicit_nesting(self):
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user