mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-22 17:47:04 +03:00
Merge pull request #3255 from jamesbeith/issues/#3254-display-value
Add a method to return the string value used in `choices` of a `RelatedField`
This commit is contained in:
commit
2d5e8dea15
|
@ -537,6 +537,14 @@ If you explicitly specify a relational field pointing to a
|
|||
``ManyToManyField`` with a through model, be sure to set ``read_only``
|
||||
to ``True``.
|
||||
|
||||
## The `display_value` method
|
||||
|
||||
The `__str__` (`__unicode__` on Python 2) method of the model will be called to generate string representations of the objects used to populate the `choices` property. These choices are used to populate select HTML inputs in the browsable API. To provide customized representations for such inputs, override `display_value` of a `RelatedField` subclass. This method will receive a model object, and should return a string suitable for representing it. For example:
|
||||
|
||||
class TrackPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
|
||||
def display_value(self, instance):
|
||||
return 'Track: %s' % (instance.title)
|
||||
|
||||
---
|
||||
|
||||
# Third Party Packages
|
||||
|
|
|
@ -148,7 +148,7 @@ class RelatedField(Field):
|
|||
return OrderedDict([
|
||||
(
|
||||
six.text_type(self.to_representation(item)),
|
||||
six.text_type(item)
|
||||
self.display_value(item)
|
||||
)
|
||||
for item in queryset
|
||||
])
|
||||
|
@ -160,6 +160,9 @@ class RelatedField(Field):
|
|||
def iter_options(self):
|
||||
return iter_options(self.grouped_choices)
|
||||
|
||||
def display_value(self, instance):
|
||||
return six.text_type(instance)
|
||||
|
||||
|
||||
class StringRelatedField(RelatedField):
|
||||
"""
|
||||
|
|
|
@ -21,7 +21,7 @@ from django.utils import six
|
|||
|
||||
from rest_framework import serializers
|
||||
from rest_framework.compat import DurationField as ModelDurationField
|
||||
from rest_framework.compat import unicode_repr
|
||||
from rest_framework.compat import OrderedDict, unicode_repr
|
||||
|
||||
|
||||
def dedent(blocktext):
|
||||
|
@ -546,6 +546,50 @@ class TestRelationalFieldMappings(TestCase):
|
|||
self.assertEqual(unicode_repr(TestSerializer()), expected)
|
||||
|
||||
|
||||
class DisplayValueTargetModel(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
def __str__(self):
|
||||
return '%s Color' % (self.name)
|
||||
|
||||
|
||||
class DisplayValueModel(models.Model):
|
||||
color = models.ForeignKey(DisplayValueTargetModel)
|
||||
|
||||
|
||||
class TestRelationalFieldDisplayValue(TestCase):
|
||||
def setUp(self):
|
||||
DisplayValueTargetModel.objects.bulk_create([
|
||||
DisplayValueTargetModel(name='Red'),
|
||||
DisplayValueTargetModel(name='Yellow'),
|
||||
DisplayValueTargetModel(name='Green'),
|
||||
])
|
||||
|
||||
def test_default_display_value(self):
|
||||
class TestSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = DisplayValueModel
|
||||
|
||||
serializer = TestSerializer()
|
||||
expected = OrderedDict([('1', 'Red Color'), ('2', 'Yellow Color'), ('3', 'Green Color')])
|
||||
self.assertEqual(serializer.fields['color'].choices, expected)
|
||||
|
||||
def test_custom_display_value(self):
|
||||
class TestField(serializers.PrimaryKeyRelatedField):
|
||||
def display_value(self, instance):
|
||||
return 'My %s Color' % (instance.name)
|
||||
|
||||
class TestSerializer(serializers.ModelSerializer):
|
||||
color = TestField(queryset=DisplayValueTargetModel.objects.all())
|
||||
|
||||
class Meta:
|
||||
model = DisplayValueModel
|
||||
|
||||
serializer = TestSerializer()
|
||||
expected = OrderedDict([('1', 'My Red Color'), ('2', 'My Yellow Color'), ('3', 'My Green Color')])
|
||||
self.assertEqual(serializer.fields['color'].choices, expected)
|
||||
|
||||
|
||||
class TestIntegration(TestCase):
|
||||
def setUp(self):
|
||||
self.foreign_key_target = ForeignKeyTargetModel.objects.create(
|
||||
|
|
Loading…
Reference in New Issue
Block a user