38 lines
1.6 KiB
Python
38 lines
1.6 KiB
Python
"""Fields useful for edX API implementations."""
|
|
from django.core.exceptions import ValidationError
|
|
|
|
from rest_framework.serializers import CharField, Field
|
|
|
|
|
|
class ExpandableField(Field):
|
|
"""Field that can dynamically use a more detailed serializer based on a user-provided "expand" parameter."""
|
|
def __init__(self, **kwargs):
|
|
"""Sets up the ExpandableField with the collapsed and expanded versions of the serializer."""
|
|
assert 'collapsed_serializer' in kwargs and 'expanded_serializer' in kwargs
|
|
self.collapsed = kwargs.pop('collapsed_serializer')
|
|
self.expanded = kwargs.pop('expanded_serializer')
|
|
super(ExpandableField, self).__init__(**kwargs)
|
|
|
|
def field_to_native(self, obj, field_name):
|
|
"""Converts obj to a native representation, using the expanded serializer if the context requires it."""
|
|
if 'expand' in self.context and field_name in self.context['expand']:
|
|
self.expanded.initialize(self, field_name)
|
|
return self.expanded.field_to_native(obj, field_name)
|
|
else:
|
|
self.collapsed.initialize(self, field_name)
|
|
return self.collapsed.field_to_native(obj, field_name)
|
|
|
|
|
|
class NonEmptyCharField(CharField):
|
|
"""
|
|
A field that enforces non-emptiness even for partial updates.
|
|
|
|
This is necessary because prior to version 3, DRF skips validation for empty
|
|
values. Thus, CharField's min_length and RegexField cannot be used to
|
|
enforce this constraint.
|
|
"""
|
|
def validate(self, value):
|
|
super(NonEmptyCharField, self).validate(value)
|
|
if not value:
|
|
raise ValidationError(self.error_messages["required"])
|