Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow unexpected values for ChoiceField/MultipleChoiceField representations #2940

Merged
merged 2 commits into from
May 15, 2015
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions rest_framework/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -1042,10 +1042,16 @@ def to_internal_value(self, data):
except KeyError:
self.fail('invalid_choice', input=data)

def representation_value(self, value):
try:
return self.choice_strings_to_values[six.text_type(value)]
except KeyError:
return value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably prefer to drop the indirection & just include this logic in the code as-is without the extra method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was actually my first attempt, although how would you inline a try/except inside a list comprehension? Was asking on #django and was told it may be possible with a generator expression & yielding?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yup, I see that now. Missed the wrapping list comprehension.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you just do if six.text_type(value) in self.choice_strings_to_values instead of relying on a try/except here?

(Not suggesting that we remove the extra method, just commenting on the try/except that is being used)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, perhaps a self.choice_strings_to_values.get(six.text_type(value), value) is better here?


def to_representation(self, value):
if value in ('', None):
return value
return self.choice_strings_to_values[six.text_type(value)]
return self.representation_value(value)


class MultipleChoiceField(ChoiceField):
Expand Down Expand Up @@ -1073,7 +1079,7 @@ def to_internal_value(self, data):

def to_representation(self, value):
return set([
self.choice_strings_to_values[six.text_type(item)] for item in value
self.representation_value(item) for item in value
])


Expand Down
5 changes: 3 additions & 2 deletions tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,8 @@ class TestChoiceField(FieldValues):
}
outputs = {
'good': 'good',
'': ''
'': '',
'amazing': 'amazing',
}
field = serializers.ChoiceField(
choices=[
Expand Down Expand Up @@ -1005,7 +1006,7 @@ class TestMultipleChoiceField(FieldValues):
('aircon', 'incorrect'): ['"incorrect" is not a valid choice.']
}
outputs = [
(['aircon', 'manual'], set(['aircon', 'manual']))
(['aircon', 'manual', 'incorrect'], set(['aircon', 'manual', 'incorrect']))
]
field = serializers.MultipleChoiceField(
choices=[
Expand Down