django-fobi/src/fobi/contrib/apps/drf_integration/fields.py
Artur Barseghyan 7a922613ae prepare 0.11.4
2017-05-12 00:52:58 +02:00

95 lines
2.6 KiB
Python

import copy
import six
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from rest_framework.fields import (
Field,
empty,
MultipleChoiceField,
)
__title__ = 'fobi.contrib.apps.drf_integration.fields'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2016-2017 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = (
'ContentImageField',
'ContentTextField',
'ContentVideoField',
'MultipleChoiceWithMaxField',
'NoneField',
)
class MultipleChoiceWithMaxField(MultipleChoiceField):
"""MultipleChoiceWithMaxField."""
default_error_messages = copy.copy(
MultipleChoiceField.default_error_messages
)
default_error_messages.update({
'max_choices': _('Max number of choices reached.'),
})
def __init__(self, *args, **kwargs):
self.max_choices = kwargs.pop('max_choices', None)
super(MultipleChoiceWithMaxField, self).__init__(*args, **kwargs)
def to_internal_value(self, data):
if self.max_choices:
if len(data) > self.max_choices:
self.fail('max_choices')
return super(
MultipleChoiceWithMaxField,
self
).to_internal_value(data)
class NoneField(Field):
"""NoneField."""
default_error_messages = {}
initial = ''
default_empty_html = ''
def __init__(self, **kwargs):
self.allow_blank = True
self.trim_whitespace = kwargs.pop('trim_whitespace', True)
self.raw_data = kwargs.pop('raw_data', {})
super(NoneField, self).__init__(**kwargs)
def run_validation(self, data=empty):
return ''
def to_internal_value(self, data):
# We're lenient with allowing basic numerics to be coerced into
# strings, but other types should fail. Eg. unclear if booleans
# should represent as `true` or `True`, and composites such as lists
# are likely user error.
_not_isinstance_str_int_float = not isinstance(
data, six.string_types + six.integer_types + (float,)
)
if isinstance(data, bool) or _not_isinstance_str_int_float:
self.fail('invalid')
value = six.text_type(data)
return value.strip() if self.trim_whitespace else value
def to_representation(self, value):
return mark_safe(six.text_type(value))
class ContentTextField(NoneField):
"""Content text field."""
class ContentImageField(NoneField):
"""Content image field."""
class ContentVideoField(NoneField):
"""Content video field."""