mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-09 08:00:52 +03:00
Tests for field choices
This commit is contained in:
parent
5d80f7f932
commit
f22d0afc3d
|
@ -102,6 +102,7 @@ class Field(object):
|
||||||
'null': _('This field may not be null.')
|
'null': _('This field may not be null.')
|
||||||
}
|
}
|
||||||
default_validators = []
|
default_validators = []
|
||||||
|
default_empty_html = None
|
||||||
|
|
||||||
def __init__(self, read_only=False, write_only=False,
|
def __init__(self, read_only=False, write_only=False,
|
||||||
required=None, default=empty, initial=None, source=None,
|
required=None, default=empty, initial=None, source=None,
|
||||||
|
@ -185,6 +186,11 @@ class Field(object):
|
||||||
Given the *incoming* primative data, return the value for this field
|
Given the *incoming* primative data, return the value for this field
|
||||||
that should be validated and transformed to a native value.
|
that should be validated and transformed to a native value.
|
||||||
"""
|
"""
|
||||||
|
if html.is_html_input(dictionary):
|
||||||
|
# HTML forms will represent empty fields as '', and cannot
|
||||||
|
# represent None or False values directly.
|
||||||
|
ret = dictionary.get(self.field_name, '')
|
||||||
|
return self.default_empty_html if (ret == '') else ret
|
||||||
return dictionary.get(self.field_name, empty)
|
return dictionary.get(self.field_name, empty)
|
||||||
|
|
||||||
def get_attribute(self, instance):
|
def get_attribute(self, instance):
|
||||||
|
@ -236,9 +242,6 @@ class Field(object):
|
||||||
Test the given value against all the validators on the field,
|
Test the given value against all the validators on the field,
|
||||||
and either raise a `ValidationError` or simply return.
|
and either raise a `ValidationError` or simply return.
|
||||||
"""
|
"""
|
||||||
if value in (None, '', [], (), {}):
|
|
||||||
return
|
|
||||||
|
|
||||||
errors = []
|
errors = []
|
||||||
for validator in self.validators:
|
for validator in self.validators:
|
||||||
try:
|
try:
|
||||||
|
@ -282,16 +285,10 @@ class BooleanField(Field):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid': _('`{input}` is not a valid boolean.')
|
'invalid': _('`{input}` is not a valid boolean.')
|
||||||
}
|
}
|
||||||
|
default_empty_html = False
|
||||||
TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True))
|
TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True))
|
||||||
FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False))
|
FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False))
|
||||||
|
|
||||||
def get_value(self, dictionary):
|
|
||||||
if html.is_html_input(dictionary):
|
|
||||||
# HTML forms do not send a `False` value on an empty checkbox,
|
|
||||||
# so we override the default empty value to be False.
|
|
||||||
return dictionary.get(self.field_name, False)
|
|
||||||
return dictionary.get(self.field_name, empty)
|
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
if data in self.TRUE_VALUES:
|
if data in self.TRUE_VALUES:
|
||||||
return True
|
return True
|
||||||
|
@ -315,6 +312,7 @@ class CharField(Field):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'blank': _('This field may not be blank.')
|
'blank': _('This field may not be blank.')
|
||||||
}
|
}
|
||||||
|
default_empty_html = ''
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.allow_blank = kwargs.pop('allow_blank', False)
|
self.allow_blank = kwargs.pop('allow_blank', False)
|
||||||
|
@ -323,6 +321,9 @@ class CharField(Field):
|
||||||
super(CharField, self).__init__(**kwargs)
|
super(CharField, self).__init__(**kwargs)
|
||||||
|
|
||||||
def run_validation(self, data=empty):
|
def run_validation(self, data=empty):
|
||||||
|
# Test for the empty string here so that it does not get validated,
|
||||||
|
# and so that subclasses do not need to handle it explicitly
|
||||||
|
# inside the `to_internal_value()` method.
|
||||||
if data == '':
|
if data == '':
|
||||||
if not self.allow_blank:
|
if not self.allow_blank:
|
||||||
self.fail('blank')
|
self.fail('blank')
|
||||||
|
|
|
@ -411,6 +411,9 @@ class ModelSerializer(Serializer):
|
||||||
# `ModelField`, which is used when no other typed field
|
# `ModelField`, which is used when no other typed field
|
||||||
# matched to the model field.
|
# matched to the model field.
|
||||||
kwargs.pop('model_field', None)
|
kwargs.pop('model_field', None)
|
||||||
|
if not issubclass(field_cls, CharField):
|
||||||
|
# `allow_blank` is only valid for textual fields.
|
||||||
|
kwargs.pop('allow_blank', None)
|
||||||
|
|
||||||
elif field_name in info.relations:
|
elif field_name in info.relations:
|
||||||
# Create forward and reverse relationships.
|
# Create forward and reverse relationships.
|
||||||
|
|
|
@ -49,8 +49,9 @@ def get_field_kwargs(field_name, model_field):
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
validator_kwarg = model_field.validators
|
validator_kwarg = model_field.validators
|
||||||
|
|
||||||
if model_field.null or model_field.blank:
|
# The following will only be used by ModelField classes.
|
||||||
kwargs['required'] = False
|
# Gets removed for everything else.
|
||||||
|
kwargs['model_field'] = model_field
|
||||||
|
|
||||||
if model_field.verbose_name and needs_label(model_field, field_name):
|
if model_field.verbose_name and needs_label(model_field, field_name):
|
||||||
kwargs['label'] = capfirst(model_field.verbose_name)
|
kwargs['label'] = capfirst(model_field.verbose_name)
|
||||||
|
@ -59,23 +60,26 @@ def get_field_kwargs(field_name, model_field):
|
||||||
kwargs['help_text'] = model_field.help_text
|
kwargs['help_text'] = model_field.help_text
|
||||||
|
|
||||||
if isinstance(model_field, models.AutoField) or not model_field.editable:
|
if isinstance(model_field, models.AutoField) or not model_field.editable:
|
||||||
|
# If this field is read-only, then return early.
|
||||||
|
# Further keyword arguments are not valid.
|
||||||
kwargs['read_only'] = True
|
kwargs['read_only'] = True
|
||||||
# Read only implies that the field is not required.
|
return kwargs
|
||||||
# We have a cleaner repr on the instance if we don't set it.
|
|
||||||
kwargs.pop('required', None)
|
|
||||||
|
|
||||||
if model_field.has_default():
|
if model_field.has_default():
|
||||||
kwargs['default'] = model_field.get_default()
|
kwargs['required'] = False
|
||||||
# Having a default implies that the field is not required.
|
|
||||||
# We have a cleaner repr on the instance if we don't set it.
|
|
||||||
kwargs.pop('required', None)
|
|
||||||
|
|
||||||
if model_field.flatchoices:
|
if model_field.flatchoices:
|
||||||
# If this model field contains choices, then return now,
|
# If this model field contains choices, then return early.
|
||||||
# any further keyword arguments are not valid.
|
# Further keyword arguments are not valid.
|
||||||
kwargs['choices'] = model_field.flatchoices
|
kwargs['choices'] = model_field.flatchoices
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
if model_field.null:
|
||||||
|
kwargs['allow_null'] = True
|
||||||
|
|
||||||
|
if model_field.blank:
|
||||||
|
kwargs['allow_blank'] = True
|
||||||
|
|
||||||
# Ensure that max_length is passed explicitly as a keyword arg,
|
# Ensure that max_length is passed explicitly as a keyword arg,
|
||||||
# rather than as a validator.
|
# rather than as a validator.
|
||||||
max_length = getattr(model_field, 'max_length', None)
|
max_length = getattr(model_field, 'max_length', None)
|
||||||
|
@ -88,7 +92,10 @@ def get_field_kwargs(field_name, model_field):
|
||||||
|
|
||||||
# Ensure that min_length is passed explicitly as a keyword arg,
|
# Ensure that min_length is passed explicitly as a keyword arg,
|
||||||
# rather than as a validator.
|
# rather than as a validator.
|
||||||
min_length = getattr(model_field, 'min_length', None)
|
min_length = next((
|
||||||
|
validator.limit_value for validator in validator_kwarg
|
||||||
|
if isinstance(validator, validators.MinLengthValidator)
|
||||||
|
), None)
|
||||||
if min_length is not None:
|
if min_length is not None:
|
||||||
kwargs['min_length'] = min_length
|
kwargs['min_length'] = min_length
|
||||||
validator_kwarg = [
|
validator_kwarg = [
|
||||||
|
@ -153,20 +160,9 @@ def get_field_kwargs(field_name, model_field):
|
||||||
if decimal_places is not None:
|
if decimal_places is not None:
|
||||||
kwargs['decimal_places'] = decimal_places
|
kwargs['decimal_places'] = decimal_places
|
||||||
|
|
||||||
if isinstance(model_field, models.BooleanField):
|
|
||||||
# models.BooleanField has `blank=True`, but *is* actually
|
|
||||||
# required *unless* a default is provided.
|
|
||||||
# Also note that Django<1.6 uses `default=False` for
|
|
||||||
# models.BooleanField, but Django>=1.6 uses `default=None`.
|
|
||||||
kwargs.pop('required', None)
|
|
||||||
|
|
||||||
if validator_kwarg:
|
if validator_kwarg:
|
||||||
kwargs['validators'] = validator_kwarg
|
kwargs['validators'] = validator_kwarg
|
||||||
|
|
||||||
# The following will only be used by ModelField classes.
|
|
||||||
# Gets removed for everything else.
|
|
||||||
kwargs['model_field'] = model_field
|
|
||||||
|
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
|
@ -188,16 +184,22 @@ def get_relation_kwargs(field_name, relation_info):
|
||||||
kwargs.pop('queryset', None)
|
kwargs.pop('queryset', None)
|
||||||
|
|
||||||
if model_field:
|
if model_field:
|
||||||
if model_field.null or model_field.blank:
|
|
||||||
kwargs['required'] = False
|
|
||||||
if model_field.verbose_name and needs_label(model_field, field_name):
|
if model_field.verbose_name and needs_label(model_field, field_name):
|
||||||
kwargs['label'] = capfirst(model_field.verbose_name)
|
kwargs['label'] = capfirst(model_field.verbose_name)
|
||||||
if not model_field.editable:
|
|
||||||
kwargs['read_only'] = True
|
|
||||||
kwargs.pop('queryset', None)
|
|
||||||
help_text = clean_manytomany_helptext(model_field.help_text)
|
help_text = clean_manytomany_helptext(model_field.help_text)
|
||||||
if help_text:
|
if help_text:
|
||||||
kwargs['help_text'] = help_text
|
kwargs['help_text'] = help_text
|
||||||
|
if not model_field.editable:
|
||||||
|
kwargs['read_only'] = True
|
||||||
|
kwargs.pop('queryset', None)
|
||||||
|
if kwargs.get('read_only', False):
|
||||||
|
# If this field is read-only, then return early.
|
||||||
|
# No further keyword arguments are valid.
|
||||||
|
return kwargs
|
||||||
|
if model_field.has_default():
|
||||||
|
kwargs['required'] = False
|
||||||
|
if model_field.null:
|
||||||
|
kwargs['allow_null'] = True
|
||||||
|
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
from rest_framework import fields
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
|
|
||||||
class TestFieldOptions:
|
|
||||||
def test_required(self):
|
|
||||||
"""
|
|
||||||
By default a field must be included in the input.
|
|
||||||
"""
|
|
||||||
field = fields.IntegerField()
|
|
||||||
with pytest.raises(fields.ValidationError) as exc_info:
|
|
||||||
field.run_validation()
|
|
||||||
assert exc_info.value.messages == ['This field is required.']
|
|
||||||
|
|
||||||
def test_not_required(self):
|
|
||||||
"""
|
|
||||||
If `required=False` then a field may be omitted from the input.
|
|
||||||
"""
|
|
||||||
field = fields.IntegerField(required=False)
|
|
||||||
with pytest.raises(fields.SkipField):
|
|
||||||
field.run_validation()
|
|
||||||
|
|
||||||
def test_disallow_null(self):
|
|
||||||
"""
|
|
||||||
By default `None` is not a valid input.
|
|
||||||
"""
|
|
||||||
field = fields.IntegerField()
|
|
||||||
with pytest.raises(fields.ValidationError) as exc_info:
|
|
||||||
field.run_validation(None)
|
|
||||||
assert exc_info.value.messages == ['This field may not be null.']
|
|
||||||
|
|
||||||
def test_allow_null(self):
|
|
||||||
"""
|
|
||||||
If `allow_null=True` then `None` is a valid input.
|
|
||||||
"""
|
|
||||||
field = fields.IntegerField(allow_null=True)
|
|
||||||
output = field.run_validation(None)
|
|
||||||
assert output is None
|
|
||||||
|
|
||||||
def test_disallow_blank(self):
|
|
||||||
"""
|
|
||||||
By default '' is not a valid input.
|
|
||||||
"""
|
|
||||||
field = fields.CharField()
|
|
||||||
with pytest.raises(fields.ValidationError) as exc_info:
|
|
||||||
field.run_validation('')
|
|
||||||
assert exc_info.value.messages == ['This field may not be blank.']
|
|
||||||
|
|
||||||
def test_allow_blank(self):
|
|
||||||
"""
|
|
||||||
If `allow_blank=True` then '' is a valid input.
|
|
||||||
"""
|
|
||||||
field = fields.CharField(allow_blank=True)
|
|
||||||
output = field.run_validation('')
|
|
||||||
assert output is ''
|
|
|
@ -6,6 +6,73 @@ import django
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
# Tests for field keyword arguments and core functionality.
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
|
class TestFieldOptions:
|
||||||
|
def test_required(self):
|
||||||
|
"""
|
||||||
|
By default a field must be included in the input.
|
||||||
|
"""
|
||||||
|
field = fields.IntegerField()
|
||||||
|
with pytest.raises(fields.ValidationError) as exc_info:
|
||||||
|
field.run_validation()
|
||||||
|
assert exc_info.value.messages == ['This field is required.']
|
||||||
|
|
||||||
|
def test_not_required(self):
|
||||||
|
"""
|
||||||
|
If `required=False` then a field may be omitted from the input.
|
||||||
|
"""
|
||||||
|
field = fields.IntegerField(required=False)
|
||||||
|
with pytest.raises(fields.SkipField):
|
||||||
|
field.run_validation()
|
||||||
|
|
||||||
|
def test_disallow_null(self):
|
||||||
|
"""
|
||||||
|
By default `None` is not a valid input.
|
||||||
|
"""
|
||||||
|
field = fields.IntegerField()
|
||||||
|
with pytest.raises(fields.ValidationError) as exc_info:
|
||||||
|
field.run_validation(None)
|
||||||
|
assert exc_info.value.messages == ['This field may not be null.']
|
||||||
|
|
||||||
|
def test_allow_null(self):
|
||||||
|
"""
|
||||||
|
If `allow_null=True` then `None` is a valid input.
|
||||||
|
"""
|
||||||
|
field = fields.IntegerField(allow_null=True)
|
||||||
|
output = field.run_validation(None)
|
||||||
|
assert output is None
|
||||||
|
|
||||||
|
def test_disallow_blank(self):
|
||||||
|
"""
|
||||||
|
By default '' is not a valid input.
|
||||||
|
"""
|
||||||
|
field = fields.CharField()
|
||||||
|
with pytest.raises(fields.ValidationError) as exc_info:
|
||||||
|
field.run_validation('')
|
||||||
|
assert exc_info.value.messages == ['This field may not be blank.']
|
||||||
|
|
||||||
|
def test_allow_blank(self):
|
||||||
|
"""
|
||||||
|
If `allow_blank=True` then '' is a valid input.
|
||||||
|
"""
|
||||||
|
field = fields.CharField(allow_blank=True)
|
||||||
|
output = field.run_validation('')
|
||||||
|
assert output is ''
|
||||||
|
|
||||||
|
def test_default(self):
|
||||||
|
"""
|
||||||
|
If `default` is set, then omitted values get the default input.
|
||||||
|
"""
|
||||||
|
field = fields.IntegerField(default=123)
|
||||||
|
output = field.run_validation()
|
||||||
|
assert output is 123
|
||||||
|
|
||||||
|
|
||||||
|
# Tests for field input and output values.
|
||||||
|
# ----------------------------------------
|
||||||
|
|
||||||
def get_items(mapping_or_list_of_two_tuples):
|
def get_items(mapping_or_list_of_two_tuples):
|
||||||
# Tests accept either lists of two tuples, or dictionaries.
|
# Tests accept either lists of two tuples, or dictionaries.
|
||||||
if isinstance(mapping_or_list_of_two_tuples, dict):
|
if isinstance(mapping_or_list_of_two_tuples, dict):
|
|
@ -6,6 +6,7 @@ These tests deal with ensuring that we correctly map the model fields onto
|
||||||
an appropriate set of serializer fields for each case.
|
an appropriate set of serializer fields for each case.
|
||||||
"""
|
"""
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.core.validators import MaxValueValidator, MinValueValidator, MinLengthValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
@ -15,7 +16,8 @@ def dedent(blocktext):
|
||||||
return '\n'.join([line[12:] for line in blocktext.splitlines()[1:-1]])
|
return '\n'.join([line[12:] for line in blocktext.splitlines()[1:-1]])
|
||||||
|
|
||||||
|
|
||||||
# Testing regular field mappings
|
# Tests for regular field mappings.
|
||||||
|
# ---------------------------------
|
||||||
|
|
||||||
class CustomField(models.Field):
|
class CustomField(models.Field):
|
||||||
"""
|
"""
|
||||||
|
@ -24,9 +26,6 @@ class CustomField(models.Field):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
COLOR_CHOICES = (('red', 'Red'), ('blue', 'Blue'), ('green', 'Green'))
|
|
||||||
|
|
||||||
|
|
||||||
class RegularFieldsModel(models.Model):
|
class RegularFieldsModel(models.Model):
|
||||||
"""
|
"""
|
||||||
A model class for testing regular flat fields.
|
A model class for testing regular flat fields.
|
||||||
|
@ -35,7 +34,6 @@ class RegularFieldsModel(models.Model):
|
||||||
big_integer_field = models.BigIntegerField()
|
big_integer_field = models.BigIntegerField()
|
||||||
boolean_field = models.BooleanField(default=False)
|
boolean_field = models.BooleanField(default=False)
|
||||||
char_field = models.CharField(max_length=100)
|
char_field = models.CharField(max_length=100)
|
||||||
choices_field = models.CharField(max_length=100, choices=COLOR_CHOICES)
|
|
||||||
comma_seperated_integer_field = models.CommaSeparatedIntegerField(max_length=100)
|
comma_seperated_integer_field = models.CommaSeparatedIntegerField(max_length=100)
|
||||||
date_field = models.DateField()
|
date_field = models.DateField()
|
||||||
datetime_field = models.DateTimeField()
|
datetime_field = models.DateTimeField()
|
||||||
|
@ -57,6 +55,19 @@ class RegularFieldsModel(models.Model):
|
||||||
return 'method'
|
return 'method'
|
||||||
|
|
||||||
|
|
||||||
|
COLOR_CHOICES = (('red', 'Red'), ('blue', 'Blue'), ('green', 'Green'))
|
||||||
|
|
||||||
|
|
||||||
|
class FieldOptionsModel(models.Model):
|
||||||
|
value_limit_field = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(10)])
|
||||||
|
length_limit_field = models.CharField(validators=[MinLengthValidator(3)], max_length=12)
|
||||||
|
blank_field = models.CharField(blank=True, max_length=10)
|
||||||
|
null_field = models.IntegerField(null=True)
|
||||||
|
default_field = models.IntegerField(default=0)
|
||||||
|
descriptive_field = models.IntegerField(help_text='Some help text', verbose_name='A label')
|
||||||
|
choices_field = models.CharField(max_length=100, choices=COLOR_CHOICES)
|
||||||
|
|
||||||
|
|
||||||
class TestRegularFieldMappings(TestCase):
|
class TestRegularFieldMappings(TestCase):
|
||||||
def test_regular_fields(self):
|
def test_regular_fields(self):
|
||||||
"""
|
"""
|
||||||
|
@ -70,9 +81,8 @@ class TestRegularFieldMappings(TestCase):
|
||||||
TestSerializer():
|
TestSerializer():
|
||||||
auto_field = IntegerField(read_only=True)
|
auto_field = IntegerField(read_only=True)
|
||||||
big_integer_field = IntegerField()
|
big_integer_field = IntegerField()
|
||||||
boolean_field = BooleanField(default=False)
|
boolean_field = BooleanField(required=False)
|
||||||
char_field = CharField(max_length=100)
|
char_field = CharField(max_length=100)
|
||||||
choices_field = ChoiceField(choices=[('red', 'Red'), ('blue', 'Blue'), ('green', 'Green')])
|
|
||||||
comma_seperated_integer_field = CharField(max_length=100, validators=[<django.core.validators.RegexValidator object>])
|
comma_seperated_integer_field = CharField(max_length=100, validators=[<django.core.validators.RegexValidator object>])
|
||||||
date_field = DateField()
|
date_field = DateField()
|
||||||
datetime_field = DateTimeField()
|
datetime_field = DateTimeField()
|
||||||
|
@ -80,7 +90,7 @@ class TestRegularFieldMappings(TestCase):
|
||||||
email_field = EmailField(max_length=100)
|
email_field = EmailField(max_length=100)
|
||||||
float_field = FloatField()
|
float_field = FloatField()
|
||||||
integer_field = IntegerField()
|
integer_field = IntegerField()
|
||||||
null_boolean_field = BooleanField(required=False)
|
null_boolean_field = BooleanField(allow_null=True)
|
||||||
positive_integer_field = IntegerField()
|
positive_integer_field = IntegerField()
|
||||||
positive_small_integer_field = IntegerField()
|
positive_small_integer_field = IntegerField()
|
||||||
slug_field = SlugField(max_length=100)
|
slug_field = SlugField(max_length=100)
|
||||||
|
@ -92,6 +102,24 @@ class TestRegularFieldMappings(TestCase):
|
||||||
""")
|
""")
|
||||||
self.assertEqual(repr(TestSerializer()), expected)
|
self.assertEqual(repr(TestSerializer()), expected)
|
||||||
|
|
||||||
|
def test_field_options(self):
|
||||||
|
class TestSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = FieldOptionsModel
|
||||||
|
|
||||||
|
expected = dedent("""
|
||||||
|
TestSerializer():
|
||||||
|
id = IntegerField(label='ID', read_only=True)
|
||||||
|
value_limit_field = IntegerField(max_value=10, min_value=1)
|
||||||
|
length_limit_field = CharField(max_length=12, min_length=3)
|
||||||
|
blank_field = CharField(allow_blank=True, max_length=10)
|
||||||
|
null_field = IntegerField(allow_null=True)
|
||||||
|
default_field = IntegerField(required=False)
|
||||||
|
descriptive_field = IntegerField(help_text='Some help text', label='A label')
|
||||||
|
choices_field = ChoiceField(choices=[('red', 'Red'), ('blue', 'Blue'), ('green', 'Green')])
|
||||||
|
""")
|
||||||
|
self.assertEqual(repr(TestSerializer()), expected)
|
||||||
|
|
||||||
def test_method_field(self):
|
def test_method_field(self):
|
||||||
"""
|
"""
|
||||||
Properties and methods on the model should be allowed as `Meta.fields`
|
Properties and methods on the model should be allowed as `Meta.fields`
|
||||||
|
@ -178,7 +206,8 @@ class TestRegularFieldMappings(TestCase):
|
||||||
assert str(excinfo.exception) == expected
|
assert str(excinfo.exception) == expected
|
||||||
|
|
||||||
|
|
||||||
# Testing relational field mappings
|
# Tests for relational field mappings.
|
||||||
|
# ------------------------------------
|
||||||
|
|
||||||
class ForeignKeyTargetModel(models.Model):
|
class ForeignKeyTargetModel(models.Model):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user