class CollectionVersionCreateSerializer( CollectionVersionCreateOrUpdateSerializer): id = serializers.CharField( required=True, validators=[RegexValidator(regex=NAMESPACE_REGEX)], source='mnemonic') released = serializers.BooleanField(required=False) description = serializers.CharField(required=False) version_external_id = serializers.CharField(required=False) previous_version = serializers.CharField( required=False, source='previous_version_mnemonic') parent_version = serializers.CharField(required=False, source='parent_version_mnemonic') extras = serializers.WritableField(required=False) external_id = serializers.CharField(required=False) def restore_object(self, attrs, instance=None): version = CollectionVersion() version.mnemonic = attrs.get(self.Meta.lookup_field) return super(CollectionVersionCreateSerializer, self).restore_object(attrs, instance=version) def save_object(self, obj, **kwargs): request_user = self.context['request'].user snap_serializer = CollectionDetailSerializer( kwargs['versioned_object']) snapshot_data = snap_serializer.data snapshot_data.pop('references') obj.collection_snapshot = snapshot_data errors = CollectionVersion.persist_new(obj, user=request_user, **kwargs) if errors: self._errors.update(errors) else: update_children_for_resource_version.delay(obj.id, 'collection')
class ConceptVersionUpdateSerializer(serializers.Serializer): external_id = serializers.CharField(required=False) concept_class = serializers.CharField(required=False) datatype = serializers.CharField(required=False) names = LocalizedTextListField(required=False) descriptions = LocalizedTextListField(required=False, name_override='description') retired = serializers.BooleanField(required=False) extras = serializers.WritableField(required=False) update_comment = serializers.CharField(required=False) class Meta: model = ConceptVersion def restore_object(self, attrs, instance=None): instance.concept_class = attrs.get('concept_class', instance.concept_class) instance.datatype = attrs.get('datatype', instance.datatype) instance.extras = attrs.get('extras', instance.extras) instance.external_id = attrs.get('external_id', instance.external_id) instance.update_comment = attrs.get('update_comment') # Is this desired behavior?? instance.names = attrs.get('names', instance.names) # Is this desired behavior?? instance.descriptions = attrs.get('descriptions', instance.descriptions) instance.retired = attrs.get('retired', instance.retired) return instance def save_object(self, obj, **kwargs): user = self.context['request'].user errors = ConceptVersion.persist_clone(obj, user, **kwargs) self._errors.update(errors)
class NodeCreatorSerializer(NodeListSerializer): layer = serializers.WritableField(source='layer')
class ApiRecipeSerializer(CookboothModelSerializer): private = IntegerBooleanField() draft = IntegerBooleanField() added = serializers.SerializerMethodField('has_added') liked = serializers.SerializerMethodField('has_liked') shared = serializers.SerializerMethodField('has_shared') reported = serializers.SerializerMethodField('has_reported') commented = serializers.SerializerMethodField('has_commented') book_for_sale = serializers.SerializerMethodField('get_book_for_sale') bought = serializers.SerializerMethodField('has_bought_it') public_url = serializers.Field() cover_photo = serializers.SerializerMethodField('get_cover_photo') nb_added = serializers.Field('cache_added') ingredients = serializers.WritableField(required=False) tags = serializers.WritableField(required=False) products = ProductSerializer(many=True, read_only=True) class Meta: model = Recipes fields = ('id', 'creation_date', 'edit_date', 'chef', 'name', 'ingredients', 'tags', 'commensals', 'private', 'draft', 'added', 'liked', 'shared', 'reported', 'commented', 'public_url', 'cover_photo', 'nb_added', 'nb_likes', 'nb_shares', 'nb_comments', 'products', 'serves', 'prep_time', 'book_for_sale', 'bought', 'description') read_only_fields = ('chef', 'edit_date', 'creation_date') def __init__(self, *args, **kwargs): super(ApiRecipeSerializer, self).__init__(*args, **kwargs) self.user = self.context.get('user') self.return_user_properties = self.context.get( 'return_user_properties', []) def has_added(self, obj): if 'added' in self.return_user_properties: return obj.added_by(self.user) return False def has_liked(self, obj): if 'liked' in self.return_user_properties: return obj.liked_by(self.user) return False def has_shared(self, obj): if 'shared' in self.return_user_properties: return obj.shared_by(self.user) return False def has_reported(self, obj): if 'reported' in self.return_user_properties: return obj.reported_by(self.user) return False def has_commented(self, obj): if 'commented' in self.return_user_properties: return obj.commented_by(self.user) return False def get_book_for_sale(self, obj): book = obj.book_for_sale() return ApiBookMinimalSerializer(book).data if book else None def has_bought_it(self, obj): book = obj.book_for_sale() if not book: return False return book.user_has_bought_it(self.user) def get_cover_photo(self, obj): photos = obj.photos.filter(is_cover=True)[:1] if photos: photo = photos[0] if photo.s3_url: if photo.s3_url.name and photo.s3_url.name.startswith('http'): photo_url = photo.s3_url.name else: photo_url = photo.s3_url.url return { 'id': photo.pk, 'url': photo_url, 'creation_date': self.datetime_to_timestamp(photo.creation_date), 'edit_date': self.datetime_to_timestamp(photo.edit_date), } return None def transform_chef(self, obj, value): return embeded_chef_serializer(obj.chef) def transform_ingredients(self, obj, value): return [{ 'id': i.pk, 'name': i.name } for i in obj.get_sorted_ingredients()] def transform_tags(self, obj, value): return [{'id': t.pk, 'name': t.name} for t in obj.tags.all()] def restore_object(self, attrs, instance=None): self._ingredients = [ i.strip(',') for i in attrs.pop('ingredients', '').split('\n') if i ] self._tags = [ t.strip(',') for t in attrs.pop('tags', '').split(' ') if t ] return super(ApiRecipeSerializer, self).restore_object(attrs, instance) def save_object(self, obj, **kwargs): ingredients = [] for i in self._ingredients: try: db_ingredients = Ingredients.objects.filter(name=i)[:1] ing = db_ingredients[0] except (Ingredients.DoesNotExist, IndexError): ing = Ingredients.objects.create(name=i) ing.save() ingredients.append(ing) obj.set_ingredients_order(ingredients) obj.chef = self.user super(ApiRecipeSerializer, self).save_object(obj, **kwargs) RecipesHasIngredients.objects.filter(recipe=obj).delete() for ingredient in ingredients: RecipesHasIngredients.objects.get_or_create(recipe=obj, ingredient=ingredient) # obj.tags.clear() RecipesHasTags.objects.filter(recipe=obj).delete() for t in self._tags: try: db_tags = Tags.objects.filter(name=t)[:1] tag = db_tags[0] except (Tags.DoesNotExist, IndexError): tag = Tags.objects.create(name=t) tag.save() RecipesHasTags.objects.create(recipe=obj, tag=tag) def to_native(self, obj): ret = super(ApiRecipeSerializer, self).to_native(obj) if not ret['name']: del ret['name'] if not ret['cover_photo']: del ret['cover_photo'] return ret
class UserProfileSerializer(serializers.HyperlinkedModelSerializer): is_org = serializers.SerializerMethodField('is_organization') username = serializers.WritableField(source='user.username') email = serializers.WritableField(source='user.email') website = serializers.WritableField(source='home_page', required=False) gravatar = serializers.Field(source='gravatar') password = serializers.WritableField( source='user.password', widget=widgets.PasswordInput(), required=False) user = serializers.HyperlinkedRelatedField( view_name='user-detail', lookup_field='username', read_only=True) metadata = JsonField(source='metadata', required=False) id = serializers.Field(source='user.id') joined_on = serializers.Field(source='user.date_joined') class Meta: model = UserProfile fields = ('id', 'is_org', 'url', 'username', 'name', 'password', 'email', 'city', 'country', 'organization', 'website', 'twitter', 'gravatar', 'require_auth', 'user', 'metadata', 'joined_on') lookup_field = 'user' def is_organization(self, obj): return is_organization(obj) def to_native(self, obj): """ Serialize objects -> primitives. """ ret = super(UserProfileSerializer, self).to_native(obj) if 'password' in ret: del ret['password'] request = self.context['request'] \ if 'request' in self.context else None if 'email' in ret and request is None or request.user \ and not request.user.has_perm(CAN_VIEW_PROFILE, obj): del ret['email'] return ret def restore_object(self, attrs, instance=None): params = copy.deepcopy(attrs) username = attrs.get('user.username', None) password = attrs.get('user.password', None) name = attrs.get('name', None) email = attrs.get('user.email', None) if username: params['username'] = username if email: params['email'] = email if password: params.update({'password1': password, 'password2': password}) if instance: form = UserProfileForm(params, instance=instance) # form.is_valid affects instance object for partial updates [PATCH] # so only use it for full updates [PUT], i.e shallow copy effect if not self.partial and form.is_valid(): instance = form.save() # get user if email: instance.user.email = form.cleaned_data['email'] if name: first_name, last_name = _get_first_last_names(name) instance.user.first_name = first_name instance.user.last_name = last_name if email or name: instance.user.save() return super( UserProfileSerializer, self).restore_object(attrs, instance) form = RegistrationFormUserProfile(params) # does not require captcha form.REGISTRATION_REQUIRE_CAPTCHA = False if form.is_valid(): site = Site.objects.get(pk=settings.SITE_ID) new_user = RegistrationProfile.objects.create_inactive_user( username=username, password=password, email=email, site=site, send_email=True) new_user.is_active = True new_user.save() created_by = self.context['request'].user created_by = None if created_by.is_anonymous() else created_by profile = UserProfile( user=new_user, name=attrs.get('name', u''), created_by=created_by, city=attrs.get('city', u''), country=attrs.get('country', u''), organization=attrs.get('organization', u''), home_page=attrs.get('home_page', u''), twitter=attrs.get('twitter', u'')) return profile else: self.errors.update(form.errors) return attrs def validate_username(self, attrs, source): request_method = self.context['request'].method if request_method == 'PATCH' and source not in attrs: return attrs current_username = self.object.user.username if self.object else None username = attrs[source].lower() is_edit = current_username is not None and current_username != username form = RegistrationFormUserProfile if username in form._reserved_usernames and is_edit: raise ValidationError( u"%s is a reserved name, please choose another" % username) elif not form.legal_usernames_re.search(username): raise ValidationError( u'username may only contain alpha-numeric characters and ' u'underscores') try: User.objects.get(username=username) except User.DoesNotExist: attrs[source] = username else: if not current_username or is_edit: raise ValidationError(u'%s already exists' % username) return attrs
class ProfileSerializer(serializers.ModelSerializer): username = serializers.WritableField(source='user.username') display_name = serializers.WritableField(source='name', required=False) date_joined = DateTimeUTCField(source='user.date_joined', read_only=True) avatar = serializers.SerializerMethodField('get_avatar_url') email = (PermissionMod(serializers.WritableField, permissions=[OnlySelf])(source='user.email', required=False)) settings = (PermissionMod(UserSettingSerializer, permissions=[OnlySelf])(many=True, read_only=True)) helpfulness = serializers.Field(source='answer_helpfulness') answer_count = serializers.SerializerMethodField('get_answer_count') question_count = serializers.SerializerMethodField('get_question_count') solution_count = serializers.SerializerMethodField('get_solution_count') # These are write only fields. It is very important they stays that way! password = serializers.WritableField(source='user.password', write_only=True) is_active = (PermissionMod(serializers.BooleanField, permissions=[OnlySelf])(source='user.is_active', read_only=True)) class Meta: model = Profile fields = [ 'username', 'display_name', 'date_joined', 'avatar', 'bio', 'website', 'twitter', 'facebook', 'mozillians', 'irc_handle', 'timezone', 'country', 'city', 'locale', 'email', 'settings', 'helpfulness', 'question_count', 'answer_count', 'solution_count', # Password and email are here so they can be involved in write # operations. They is marked as write-only above, so will not be # visible. 'password', 'is_active', ] def get_avatar_url(self, profile): return profile_avatar(profile.user) def get_question_count(self, profile): return num_questions(profile.user) def get_answer_count(self, profile): return num_answers(profile.user) def get_solution_count(self, profile): return num_solutions(profile.user) def restore_object(self, attrs, instance=None): """ Override the default behavior to make a user if one doesn't exist. This user may not be saved here, but will be saved if/when the .save() method of the serializer is called. """ instance = (super(ProfileSerializer, self).restore_object(attrs, instance)) if instance.user_id is None: # The Profile doesn't have a user, so create one. If an email is # specified, the user will be inactive until the email is # confirmed. Otherwise the user can be created immediately. if 'user.email' in attrs: u = RegistrationProfile.objects.create_inactive_user( attrs['user.username'], attrs['user.password'], attrs['user.email']) else: u = User(username=attrs['user.username']) u.set_password(attrs['user.password']) instance._nested_forward_relations['user'] = u return instance def validate_username(self, attrs, source): obj = self.object if obj is None: # This is a create if User.objects.filter(username=attrs['user.username']).exists(): raise ValidationError('A user with that username exists') else: # This is an update new_username = attrs.get('user.username', obj.user.username) if new_username != obj.user.username: raise ValidationError("Can't change this field.") if re.match(r'^[\w.-]{4,30}$', attrs['user.username']) is None: raise ValidationError( 'Usernames may only be letters, numbers, "." and "-".') return attrs def validate_display_name(self, attrs, source): if attrs.get('name') is None: attrs['name'] = attrs.get('user.username') return attrs def validate_email(self, attrs, source): email = attrs.get('user.email') if email and User.objects.filter(email=email).exists(): raise ValidationError('A user with that email address ' 'already exists.') return attrs
class UserProfileSerializer(serializers.HyperlinkedModelSerializer): username = serializers.WritableField(source='user.username') email = serializers.WritableField(source='user.email') website = serializers.WritableField(source='home_page', required=False) gravatar = serializers.Field(source='gravatar') password = serializers.WritableField(source='user.password', widget=widgets.PasswordInput(), required=False) user = serializers.HyperlinkedRelatedField(view_name='user-detail', lookup_field='username', read_only=True) class Meta: model = UserProfile fields = ('url', 'username', 'name', 'password', 'email', 'city', 'country', 'organization', 'website', 'twitter', 'gravatar', 'require_auth', 'user') lookup_field = 'user' def to_native(self, obj): """ Serialize objects -> primitives. """ ret = super(UserProfileSerializer, self).to_native(obj) if 'password' in ret: del ret['password'] return ret def restore_object(self, attrs, instance=None): def _get_first_last_names(name): name_split = name.split() first_name = name_split[0] last_name = u'' if len(name_split) > 1: last_name = u' '.join(name_split[1:]) return first_name, last_name params = copy.deepcopy(attrs) username = attrs.get('user.username', None) password = attrs.get('user.password', None) name = attrs.get('name', None) email = attrs.get('user.email', None) if username: params['username'] = username if email: params['email'] = email if password: params.update({'password1': password, 'password2': password}) if instance: form = UserProfileForm(params, instance=instance) # form.is_valid affects instance object for partial updates [PATCH] # so only use it for full updates [PUT], i.e shallow copy effect if not self.partial and form.is_valid(): instance = form.save() # get user if email: instance.user.email = form.cleaned_data['email'] if name: first_name, last_name = _get_first_last_names(name) instance.user.first_name = first_name instance.user.last_name = last_name if email or name: instance.user.save() return super(UserProfileSerializer, self).restore_object(attrs, instance) #return instance # TODO: updates form = RegistrationFormUserProfile(params) if form.is_valid(): first_name, last_name = _get_first_last_names(name) new_user = User(username=username, first_name=first_name, last_name=last_name, email=email) new_user.set_password(password) new_user.save() created_by = self.context['request'].user profile = UserProfile(user=new_user, name=attrs.get('name', u''), created_by=created_by, city=attrs.get('city', u''), country=attrs.get('country', u''), organization=attrs.get('organization', u''), home_page=attrs.get('home_page', u''), twitter=attrs.get('twitter', u'')) return profile else: self.errors.update(form.errors) return attrs
class JobExclusionSerializer(serializers.ModelSerializer): info = serializers.WritableField() class Meta: model = models.JobExclusion
class OrganizationSerializer(serializers.HyperlinkedModelSerializer): org = serializers.WritableField(source='user.username') user = serializers.HyperlinkedRelatedField( view_name='user-detail', lookup_field='username', read_only=True) creator = serializers.HyperlinkedRelatedField( view_name='user-detail', lookup_field='username', read_only=True) users = serializers.SerializerMethodField('get_org_permissions') class Meta: model = OrganizationProfile lookup_field = 'user' exclude = ('created_by', 'is_organization', 'organization') def restore_object(self, attrs, instance=None): if instance: return super(OrganizationSerializer, self)\ .restore_object(attrs, instance) org = attrs.get('user.username', None) org_name = attrs.get('name', None) org_exists = False creator = None try: User.objects.get(username=org) except User.DoesNotExist: pass else: self.errors['org'] = u'Organization %s already exists.' % org org_exists = True if 'request' in self.context: creator = self.context['request'].user if org and org_name and creator and not org_exists: attrs['organization'] = org_name orgprofile = tools.create_organization_object(org, creator, attrs) return orgprofile if not org: self.errors['org'] = u'org is required!' if not org_name: self.errors['name'] = u'name is required!' return attrs def validate_org(self, attrs, source): org = attrs[source].lower() if org in RegistrationFormUserProfile._reserved_usernames: raise ValidationError( u"%s is a reserved name, please choose another" % org) elif not RegistrationFormUserProfile.legal_usernames_re.search(org): raise ValidationError( u'organization may only contain alpha-numeric characters and ' u'underscores') try: User.objects.get(username=org) except User.DoesNotExist: attrs[source] = org return attrs raise ValidationError(u'%s already exists' % org) def get_org_permissions(self, obj): members = get_organization_members(obj) if obj else [] return [{ 'user': u.username, 'role': get_role_in_org(u, obj) } for u in members]
def mandatory_fields(self): return { "datetime": serializers.WritableField(), "value": serializers.WritableField(), }
class DeviceAddSerializer(NodeDeviceListSerializer): """ Serializer for Device Creation """ node = serializers.WritableField(source='node_id') type = serializers.WritableField(source='type') details = serializers.HyperlinkedIdentityField( view_name='api_device_details')
class CardSerializer(DynamicFieldsModelSerializer): created_by = NestedUserSerializer(read_only=True) modified_by = NestedUserSerializer(read_only=True) thumbnail_xs_path = serializers.Field(source='signed_thumbnail_xs_path') thumbnail_sm_path = serializers.Field(source='signed_thumbnail_sm_path') thumbnail_md_path = serializers.Field(source='signed_thumbnail_md_path') thumbnail_lg_path = serializers.Field(source='signed_thumbnail_lg_path') html_url = serializers.Field() download_html_url = serializers.Field() original_html_url = serializers.Field() metadata = serializers.WritableField(required=False, source='metadata') class Meta: model = Card read_only_fields = ('slug', 'stack', 'comments_count') exclude = ('data', ) def validate_metadata(self, attrs, source): metadata = attrs.get(source) valid_metadata_keys = ['pattern'] validation_message = 'Invalid metadata.' self.valid_metadata = {} if not metadata: return attrs if not isinstance(metadata, dict): raise serializers.ValidationError(validation_message) for key in metadata.keys(): if key not in valid_metadata_keys: raise serializers.ValidationError(validation_message) self.valid_metadata = metadata return attrs def validate_content(self, attrs, source): content = attrs.get(source) card_type = attrs.get('type') if card_type != 'stack' and not content: raise serializers.ValidationError(self.error_messages['required']) return attrs def save_object(self, obj, **kwargs): created = bool(obj.pk) featured_diff = obj.get_field_diff('featured') user = self.context['request'].user if not created: obj.created_by = user obj.modified_by = user valid_metadata = getattr(self, 'valid_metadata', None) if obj.data and valid_metadata: obj.data.update(valid_metadata) elif valid_metadata: obj.data = valid_metadata super(CardSerializer, self).save_object(obj, **kwargs) # Try to request previews for new card if not created: obj.request_previews() if featured_diff and featured_diff[1]: obj.notify_featured(user) def restore_object(self, attrs, instance=None): """ Restore the model instance. """ if 'metadata' in attrs: del attrs['metadata'] return super(CardSerializer, self).restore_object(attrs, instance)
class UserProfileSerializer(serializers.HyperlinkedModelSerializer): is_org = serializers.SerializerMethodField('is_organization') username = serializers.WritableField(source='user.username') name = serializers.CharField(required=False) first_name = serializers.WritableField(source='user.first_name', required=False) last_name = serializers.WritableField(source='user.last_name', required=False) email = serializers.EmailField(source='user.email') website = serializers.WritableField(source='home_page', required=False) twitter = serializers.WritableField(required=False) gravatar = serializers.Field(source='gravatar') password = serializers.WritableField(source='user.password', widget=widgets.PasswordInput(), required=False) user = serializers.HyperlinkedRelatedField(view_name='user-detail', lookup_field='username', read_only=True) metadata = JsonField(source='metadata', required=False) id = serializers.Field(source='user.id') joined_on = serializers.Field(source='user.date_joined') class Meta: model = UserProfile fields = ('id', 'is_org', 'url', 'username', 'password', 'first_name', 'last_name', 'email', 'city', 'country', 'organization', 'website', 'twitter', 'gravatar', 'require_auth', 'user', 'metadata', 'joined_on', 'name') lookup_field = 'user' def is_organization(self, obj): if obj: is_org = cache.get('{}{}'.format(IS_ORG, obj.pk)) if is_org: return is_org is_org = is_organization(obj) cache.set('{}{}'.format(IS_ORG, obj.pk), is_org) return is_org def to_native(self, obj): """ Serialize objects -> primitives. """ ret = super(UserProfileSerializer, self).to_native(obj) if 'password' in ret: del ret['password'] request = self.context['request'] \ if 'request' in self.context else None if 'email' in ret and request is None or request.user \ and not request.user.has_perm(CAN_VIEW_PROFILE, obj): del ret['email'] if 'first_name' in ret: ret['name'] = u' '.join( [ret.get('first_name'), ret.get('last_name', "")]) return ret def restore_object(self, attrs, instance=None): params = copy.deepcopy(attrs) username = attrs.get('user.username', None) password = attrs.get('user.password', None) first_name = attrs.get('user.first_name', None) last_name = attrs.get('user.last_name', None) email = attrs.get('user.email', None) name = attrs.get('name', None) if username: params['username'] = username if email: params['email'] = email if password: params.update({'password1': password, 'password2': password}) if first_name: params['first_name'] = first_name if last_name: params['last_name'] = last_name # For backward compatibility, Users who still use only name if name: first_name, last_name = \ _get_first_last_names(name) params['first_name'] = first_name params['last_name'] = last_name if instance: form = UserProfileForm(params, instance=instance) # form.is_valid affects instance object for partial updates [PATCH] # so only use it for full updates [PUT], i.e shallow copy effect if not self.partial and form.is_valid(): instance = form.save() # get user if email: instance.user.email = email if first_name: instance.user.first_name = first_name if last_name: instance.user.last_name = last_name (email or first_name or last_name) and instance.user.save() return super(UserProfileSerializer, self).restore_object(attrs, instance) form = RegistrationFormUserProfile(params) # does not require captcha form.REGISTRATION_REQUIRE_CAPTCHA = False if form.is_valid(): site = Site.objects.get(pk=settings.SITE_ID) new_user = RegistrationProfile.objects.create_inactive_user( username=username, password=password, email=email, site=site, send_email=settings.SEND_EMAIL_ACTIVATION_API) new_user.is_active = True new_user.first_name = first_name new_user.last_name = last_name new_user.save() created_by = self.context['request'].user created_by = None if created_by.is_anonymous() else created_by profile = UserProfile(user=new_user, name=first_name, created_by=created_by, city=attrs.get('city', u''), country=attrs.get('country', u''), organization=attrs.get('organization', u''), home_page=attrs.get('home_page', u''), twitter=attrs.get('twitter', u'')) return profile else: self.errors.update(form.errors) return attrs def validate_username(self, attrs, source): request_method = self.context['request'].method if request_method == 'PATCH' and source not in attrs: return attrs current_username = self.object.user.username if self.object else None username = attrs[source].lower() is_edit = current_username is not None and current_username != username form = RegistrationFormUserProfile if username in form._reserved_usernames and is_edit: raise ValidationError( u"%s is a reserved name, please choose another" % username) elif not form.legal_usernames_re.search(username): raise ValidationError( u'username may only contain alpha-numeric characters and ' u'underscores') try: User.objects.get(username=username) except User.DoesNotExist: attrs[source] = username else: if not current_username or is_edit: raise ValidationError(u'%s already exists' % username) return attrs def validate_name(self, attrs, source): if (attrs.get('name') is None) and\ (attrs.get('user.first_name') is None): raise ValidationError( u"Either name or first_name should be provided") return attrs def validate_email(self, attrs, source): request_method = self.context['request'].method if request_method == 'PUT' and source in attrs: return attrs if User.objects.filter(email=attrs.get('user.email')).exists(): raise ValidationError("This email address is already in use. ") return attrs def validate_twitter(self, attrs, source): if isinstance(attrs.get('twitter'), basestring): if attrs.get('twitter'): match = re.search(r"^[A-Za-z0-9_]{1,15}$", attrs.get('twitter')) if not match: raise ValidationError("Invalid twitter username") else: attrs['twitter'] = '' return attrs
class ProfileSerializer(serializers.ModelSerializer): username = serializers.WritableField(source='user.username') display_name = serializers.WritableField(source='name', required=False) date_joined = DateTimeUTCField(source='user.date_joined', read_only=True) avatar = serializers.SerializerMethodField('get_avatar_url') email = (PermissionMod(serializers.EmailField, permissions=[OnlySelf])(source='user.email', required=True)) settings = (PermissionMod(UserSettingSerializer, permissions=[OnlySelf])(many=True, read_only=True)) helpfulness = serializers.Field(source='answer_helpfulness') answer_count = serializers.SerializerMethodField('get_answer_count') question_count = serializers.SerializerMethodField('get_question_count') solution_count = serializers.SerializerMethodField('get_solution_count') last_answer_date = serializers.SerializerMethodField( 'get_last_answer_date') is_active = serializers.BooleanField(source='user.is_active', read_only=True) # These are write only fields. It is very important they stays that way! password = serializers.WritableField(source='user.password', write_only=True) class Meta: model = Profile fields = [ 'username', 'display_name', 'date_joined', 'avatar', 'bio', 'website', 'twitter', 'facebook', 'mozillians', 'irc_handle', 'timezone', 'country', 'city', 'locale', 'email', 'settings', 'helpfulness', 'question_count', 'answer_count', 'solution_count', 'last_answer_date', # Password and email are here so they can be involved in write # operations. They is marked as write-only above, so will not be # visible. 'password', 'is_active', ] def get_avatar_url(self, profile): request = self.context.get('request') size = request.REQUEST.get('avatar_size', 48) if request else 48 return profile_avatar(profile.user, size=size) def get_question_count(self, profile): return num_questions(profile.user) def get_answer_count(self, profile): return num_answers(profile.user) def get_solution_count(self, profile): return num_solutions(profile.user) def get_last_answer_date(self, profile): last_answer = profile.user.answers.order_by('-created').first() return last_answer.created if last_answer else None def save_object(self, obj, **kwargs): """It is universally a bad idea to force_insert=True on this object. So don't.""" kwargs.pop('force_insert', None) return super(ProfileSerializer, self).save_object(obj, **kwargs) def restore_object(self, attrs, instance=None): """ Override the default behavior to make a user if one doesn't exist. This user may not be saved here, but will be saved if/when the .save() method of the serializer is called. """ instance = (super(ProfileSerializer, self).restore_object(attrs, instance)) if instance.user_id is None: # This is a bit of cheat. The user shouldn't be saved yet, but # ``create_inactive_user`` saves it, so their isn't much of a choice. u = RegistrationProfile.objects.create_inactive_user( attrs['user.username'], attrs['user.password'], attrs['user.email']) instance.user_id = u.id instance.save() return instance def validate_username(self, attrs, source): obj = self.object if obj is None: # This is a create if User.objects.filter(username=attrs['user.username']).exists(): raise ValidationError('A user with that username exists') else: # This is an update new_username = attrs.get('user.username', obj.user.username) if new_username != obj.user.username: raise ValidationError("Can't change this field.") if re.match(r'^[\w.-]{4,30}$', attrs['user.username']) is None: raise ValidationError( 'Usernames may only be letters, numbers, "." and "-".') return attrs def validate_display_name(self, attrs, source): if attrs.get('name') is None: attrs['name'] = attrs.get('user.username') return attrs def validate_email(self, attrs, source): email = attrs.get('user.email') if email and User.objects.filter(email=email).exists(): raise ValidationError('A user with that email address ' 'already exists.') return attrs
class CollectionDetailSerializer(CollectionCreateOrUpdateSerializer): type = serializers.CharField(source='resource_type', read_only=True) uuid = serializers.CharField(source='id', read_only=True) id = serializers.CharField( required=False, validators=[RegexValidator(regex=NAMESPACE_REGEX)], source='mnemonic') short_code = serializers.CharField(source='mnemonic', read_only=True) name = serializers.CharField(required=False) full_name = serializers.CharField(required=False) preferred_source = serializers.CharField(required=False) repository_type = serializers.CharField(required=False) custom_resources_linked_source = serializers.CharField(required=False) description = serializers.CharField(required=False) external_id = serializers.CharField(required=False) collection_type = serializers.CharField(required=False) custom_validation_schema = serializers.CharField(required=False) public_access = serializers.ChoiceField(required=False, choices=ACCESS_TYPE_CHOICES) default_locale = serializers.CharField(required=False) supported_locales = serializers.CharField(required=False) website = serializers.CharField(required=False) url = serializers.CharField(read_only=True) versions_url = serializers.CharField(read_only=True) concepts_url = serializers.CharField(read_only=True) mappings_url = serializers.CharField(read_only=True) owner = serializers.CharField(source='parent_resource', read_only=True) owner_type = serializers.CharField(source='parent_resource_type', read_only=True) owner_url = serializers.CharField(source='parent_url', read_only=True) versions = serializers.IntegerField(source='num_versions', read_only=True) created_on = serializers.DateTimeField(source='created_at', read_only=True) updated_on = serializers.DateTimeField(source='updated_at', read_only=True) created_by = serializers.CharField(read_only=True) updated_by = serializers.CharField(read_only=True) extras = serializers.WritableField(required=False) references = CollectionReferenceSerializer(many=True) active_concepts = serializers.SerializerMethodField( method_name='get_active_concepts') active_mappings = serializers.SerializerMethodField( method_name='get_active_mappings') def get_fields(self, *args, **kwargs): fields = super(CollectionDetailSerializer, self).get_fields(*args, **kwargs) from collection.views import INCLUDE_REFERENCES_PARAM include_references = self.context.get(INCLUDE_REFERENCES_PARAM, True) if not include_references: fields.pop('references', None) return fields def save_object(self, obj, **kwargs): request_user = kwargs.pop('user', None) or self.context['request'].user errors = Collection.persist_changes(obj, request_user, **kwargs) if errors: self._errors = self._errors or {} self._errors.update(errors) else: head_obj = obj.get_head() head_obj.update_version_data(obj) head_obj.save()
class UpdateStorySerializer(StorySerializer): chapters = serializers.WritableField(source='chapters') class Meta: model = Story
def mandatory_fields(self): return { "uuid": serializers.WritableField(), "events": EventListSerializer(), }