pulseapi/creators/serializers.py (67 lines of code) (raw):
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ObjectDoesNotExist
from pulseapi.profiles.models import UserProfile
from pulseapi.entries.models import Entry
def serialize_profile_as_creator(profile):
return {
'name': profile.name,
'profile_id': profile.id,
'is_active': profile.is_active,
}
def serialize_profile_as_v1_creator(profile):
serialized_profile = serialize_profile_as_creator(profile)
serialized_profile['creator_id'] = profile.id # we include this property only for backwards-compatibility
return serialized_profile
def get_or_create_userprofile(data, id_key):
"""
Deserialize data into a `UserProfile` object.
The `data` is checked for a value corresponding to the id_key.
If it exists, we get the corresponding `UserProfile` object, otherwise
we create a new `UserProfile` object with the name specified.
We don't save the instance to the database and that is left to
the calling function to save the instance.
Returns a dictionary with two keys - `object` and `created`,
where `object` is the retrieved or created `UserProfile` instance and
`created` is a boolean specifying whether a new instance was created
"""
profile_id = data.get(id_key)
name = data.get('name')
if not profile_id and not name:
raise ValidationError(
detail=_('A creator/profile id or a name must be provided.'),
code='missing data',
)
if profile_id:
try:
return UserProfile.objects.get(id=profile_id), False
except ObjectDoesNotExist:
raise ValidationError(
detail=_('No profile exists for the given id {id}.'.format(id=profile_id)),
code='invalid',
)
return UserProfile(custom_name=name), True
def get_entry(data):
entry_id = data.get('entry_id')
if not entry_id:
return None
try:
return Entry.objects.get(id=entry_id)
except ObjectDoesNotExist:
raise ValidationError(
detail=_('No entry exists for the given id {id}.'.format(id=entry_id)),
code='invalid',
)
def deserialize_entry_creator(data, profile_id_key):
profile, created = get_or_create_userprofile(data, profile_id_key)
entry = get_entry(data)
entry_creator_data = {
'profile': profile,
'profile_committed': not created
}
if entry:
entry_creator_data['entry'] = entry
return entry_creator_data
class CreatorSerializer(serializers.BaseSerializer):
"""
Read-only serializer that serializes creators (which are actually profile objects)
This serializer only exists for backwards-compatibility and is disfavored
over pulseapi.profiles.serializers.UserProfileBasicSerializer
"""
def to_representation(self, instance):
return serialize_profile_as_v1_creator(instance)
class RelatedEntryCreatorField(serializers.RelatedField):
def to_representation(self, instance):
return serialize_profile_as_creator(instance.profile)
def to_internal_value(self, data):
"""
Returns a dictionary:
{
'profile': deserialized instance of `UserProfile`
'profile_committed': boolean indicating whether the profile
instance is from the database or needs to be committed
}
This dictionary will also contain an `entry` if a valid `entry_id`
was passed in with the `data`
Expects either a `profile_id` or a `name` to exist in the `data`.
"""
return deserialize_entry_creator(data, 'profile_id')
class RelatedEntryCreatorV1Field(serializers.RelatedField):
def to_representation(self, instance):
return serialize_profile_as_v1_creator(instance.profile)
def to_internal_value(self, data):
"""
Returns a dictionary:
{
'profile': deserialized instance of `UserProfile`
'profile_committed': boolean indicating whether the profile
instance is from the database or needs to be committed
}
This dictionary will also contain an `entry` if a valid `entry_id`
was passed in with the `data`
Expects either a `creator_id` or a `name` to exist in the `data`.
"""
return deserialize_entry_creator(data, 'creator_id')