Skip to content

Commit e63dcab

Browse files
committed
Fix for rendering select templates on relationships
1 parent 88609ba commit e63dcab

File tree

2 files changed

+49
-28
lines changed

2 files changed

+49
-28
lines changed

rest_framework/fields.py

+34-27
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,39 @@ def flatten_choices_dict(choices):
155155
return ret
156156

157157

158+
def iter_options(grouped_choices):
159+
"""
160+
Helper function for options and option groups in templates.
161+
"""
162+
class StartOptionGroup(object):
163+
start_option_group = True
164+
end_option_group = False
165+
166+
def __init__(self, label):
167+
self.label = label
168+
169+
class EndOptionGroup(object):
170+
start_option_group = False
171+
end_option_group = True
172+
173+
class Option(object):
174+
start_option_group = False
175+
end_option_group = False
176+
177+
def __init__(self, value, display_text):
178+
self.value = value
179+
self.display_text = display_text
180+
181+
for key, value in grouped_choices.items():
182+
if isinstance(value, dict):
183+
yield StartOptionGroup(label=key)
184+
for sub_key, sub_value in value.items():
185+
yield Option(value=sub_key, display_text=sub_value)
186+
yield EndOptionGroup()
187+
else:
188+
yield Option(value=key, display_text=value)
189+
190+
158191
class CreateOnlyDefault(object):
159192
"""
160193
This class may be used to provide default values that are only used
@@ -1190,33 +1223,7 @@ def iter_options(self):
11901223
"""
11911224
Helper method for use with templates rendering select widgets.
11921225
"""
1193-
class StartOptionGroup(object):
1194-
start_option_group = True
1195-
end_option_group = False
1196-
1197-
def __init__(self, label):
1198-
self.label = label
1199-
1200-
class EndOptionGroup(object):
1201-
start_option_group = False
1202-
end_option_group = True
1203-
1204-
class Option(object):
1205-
start_option_group = False
1206-
end_option_group = False
1207-
1208-
def __init__(self, value, display_text):
1209-
self.value = value
1210-
self.display_text = display_text
1211-
1212-
for key, value in self.grouped_choices.items():
1213-
if isinstance(value, dict):
1214-
yield StartOptionGroup(label=key)
1215-
for sub_key, sub_value in value.items():
1216-
yield Option(value=sub_key, display_text=sub_value)
1217-
yield EndOptionGroup()
1218-
else:
1219-
yield Option(value=key, display_text=value)
1226+
return iter_options(self.grouped_choices)
12201227

12211228

12221229
class MultipleChoiceField(ChoiceField):

rest_framework/relations.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from rest_framework.compat import OrderedDict
1616
from rest_framework.fields import (
17-
Field, empty, get_attribute, is_simple_callable
17+
Field, empty, get_attribute, is_simple_callable, iter_options
1818
)
1919
from rest_framework.reverse import reverse
2020
from rest_framework.utils import html
@@ -153,6 +153,13 @@ def choices(self):
153153
for item in queryset
154154
])
155155

156+
@property
157+
def grouped_choices(self):
158+
return self.choices
159+
160+
def iter_options(self):
161+
return iter_options(self.grouped_choices)
162+
156163

157164
class StringRelatedField(RelatedField):
158165
"""
@@ -453,3 +460,10 @@ def to_representation(self, iterable):
453460
@property
454461
def choices(self):
455462
return self.child_relation.choices
463+
464+
@property
465+
def grouped_choices(self):
466+
return self.choices
467+
468+
def iter_options(self):
469+
return iter_options(self.grouped_choices)

0 commit comments

Comments
 (0)