Skip to content

Instantly share code, notes, and snippets.

@imomaliev
Forked from jpadilla/fields.py
Last active January 12, 2024 14:13
Show Gist options
  • Save imomaliev/77fdfd0ab5f1b324f4e496768534737e to your computer and use it in GitHub Desktop.
Save imomaliev/77fdfd0ab5f1b324f4e496768534737e to your computer and use it in GitHub Desktop.
CharacterSeparatedManyField - A Django REST framework field that separates a string with a given separator into a native list and reverts a list into a string separated with a given separator.
from rest_framework import serializers
from rest_framework.fields import empty
from rest_framework.utils import html
class CharacterSeparatedField(serializers.ListField):
"""
Character separated ListField.
Based on https://gist.github.com/jpadilla/8792723.
A field that separates a string with a given separator into
a native list and reverts a list into a string separated with a given
separator.
"""
def __init__(self, *args, **kwargs):
self.separator = kwargs.pop("separator", ",")
super().__init__(*args, **kwargs)
def to_internal_value(self, data):
data = data.split(self.separator)
return super().to_internal_value(data)
def get_value(self, dictionary):
# We override the default field access in order to support
# lists in HTML forms.
if html.is_html_input(dictionary):
# Don't return [] if the update is partial
if self.field_name not in dictionary:
if getattr(self.root, "partial", False):
return empty
return dictionary.get(self.field_name)
return dictionary.get(self.field_name, empty)
def to_representation(self, data):
data = super().to_representation(data)
return self.separator.join(data)
from rest_framework import serializers
from contrib.rest_framework import CharacterSeparatedField
class TestCharacterSeparatedManyField:
def test_field_default_separator_is_comma(self):
field = CharacterSeparatedField(child=serializers.CharField())
assert field.separator == ","
def test_field_should_accept_custom_separator(self):
field = CharacterSeparatedField(separator=".", child=serializers.CharField())
assert field.separator == "."
def test_field_to_native_should_return_str_for_given_list(self):
field = CharacterSeparatedField(child=serializers.CharField())
assert field.to_representation(["a", "b", "c"]) == "a,b,c"
def test_field_from_native_should_return_list_for_given_str(self):
field = CharacterSeparatedField(child=serializers.CharField())
assert field.to_internal_value("a,b,c") == ["a", "b", "c"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment