class ObjectViewsSerializerAdmixer(serializers.Serializer): object = serializers.CharField(max_length=1024) views = serializers.IntegerField() date = serializers.DateField(required=False)
class CartItemSerializer(serializers.ModelSerializer): quantity = serializers.IntegerField(min_value=1, max_value=100) class Meta: model = ShoppingCartItem fields = ('product', 'quantity')
class AvailabilitySerializer(serializers.Serializer): # pylint: disable=abstract-method is_available_to_buy = serializers.BooleanField() num_available = serializers.IntegerField(required=False) message = serializers.CharField()
class EnrollmentSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) name = serializers.CharField() phone = serializers.CharField() club = ClubSerializer()
class InterfaceSerializer(PrimaryModelSerializer, CableTerminationSerializer, ConnectedEndpointSerializer): url = serializers.HyperlinkedIdentityField( view_name='dcim-api:interface-detail') device = NestedDeviceSerializer() type = ChoiceField(choices=InterfaceTypeChoices) parent = NestedInterfaceSerializer(required=False, allow_null=True) lag = NestedInterfaceSerializer(required=False, allow_null=True) mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False) untagged_vlan = NestedVLANSerializer(required=False, allow_null=True) tagged_vlans = SerializedPKRelatedField(queryset=VLAN.objects.all(), serializer=NestedVLANSerializer, required=False, many=True) cable = NestedCableSerializer(read_only=True) count_ipaddresses = serializers.IntegerField(read_only=True) class Meta: model = Interface fields = [ 'id', 'url', 'display', 'device', 'name', 'label', 'type', 'enabled', 'parent', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description', 'mode', 'untagged_vlan', 'tagged_vlans', 'mark_connected', 'cable', 'cable_peer', 'cable_peer_type', 'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', 'count_ipaddresses', '_occupied', ] def validate(self, data): # Validate many-to-many VLAN assignments device = self.instance.device if self.instance else data.get('device') for vlan in data.get('tagged_vlans', []): if vlan.site not in [device.site, None]: raise serializers.ValidationError({ 'tagged_vlans': f"VLAN {vlan} must belong to the same site as the interface's parent device, or " f"it must be global." }) return super().validate(data)
class Request(serializers.Serializer): description = serializers.ChoiceField(choices=DESCRIPTION_CHOICES) location = serializers.ChoiceField(choices=LOCATION_CHOICES) page = serializers.IntegerField(default=1, min_value=1) search_from = serializers.IPAddressField(write_only=True)
class BuildingTrainingDirectionConstraintSerializer(serializers.Serializer): training_direction_id = serializers.IntegerField(required=False) id = serializers.IntegerField(required=False) building_id = serializers.IntegerField() ordering = serializers.IntegerField() remove = serializers.BooleanField(default=False)
class TPMVisitApproveSerializer(serializers.Serializer): mark_as_programmatic_visit = serializers.ListField( child=serializers.IntegerField(), required=False) approval_comment = serializers.CharField(required=False) notify_focal_point = serializers.BooleanField(required=False) notify_tpm_partner = serializers.BooleanField(required=False)
class TestSuiteHealthSerializer(serializers.Serializer): test = serializers.CharField() suite = serializers.CharField() platforms = CommaSeparatedField() repositories = CommaSeparatedField() total_alerts = serializers.IntegerField()
class ActorMovieSerializer(serializers.Serializer): idmovies = serializers.IntegerField() title = serializers.CharField() year = serializers.IntegerField()
class MovieGenreSerializer(serializers.Serializer): idmovies = serializers.IntegerField() title = serializers.CharField()
class ReviewSerializer(serializers.Serializer): title = serializers.CharField() comment = serializers.CharField() rating = serializers.IntegerField() reviewer = CustomerSerializer() to_game = GameSerializer()
class GetUsersSerializer(serializers.Serializer): query = serializers.CharField( max_length=settings.SEARCH_QUERIES_MAX_LENGTH, required=True) count = serializers.IntegerField(required=False, max_value=10)
class ThemeCompanySdViewsSerializer(serializers.Serializer): key_word = serializers.CharField(max_length=1024) views = serializers.IntegerField() date = serializers.DateField(required=False) sex = serializers.DictField(required=False, child=serializers.IntegerField(min_value=0)) age = serializers.DictField(required=False, child=serializers.IntegerField(min_value=0)) education = serializers.DictField( required=False, child=serializers.IntegerField(min_value=0)) children_lt_16 = serializers.DictField( required=False, child=serializers.IntegerField(min_value=0)) marital_status = serializers.DictField( required=False, child=serializers.IntegerField(min_value=0)) occupation = serializers.DictField( required=False, child=serializers.IntegerField(min_value=0)) group = serializers.DictField(required=False, child=serializers.IntegerField(min_value=0)) income = serializers.DictField(required=False, child=serializers.IntegerField(min_value=0)) region = serializers.DictField(required=False, child=serializers.IntegerField(min_value=0)) typeNP = serializers.DictField(required=False, child=serializers.IntegerField(min_value=0)) def to_internal_value(self, data): date = data.pop("upload_info__title") try: start_period = datetime.strptime(date, "%m-%Y") end_period = start_period + timedelta( calendar.monthrange(start_period.year, start_period.month)[1]) except ValueError: try: start_period = datetime.strptime(date, "%w-%W-%Y") end_period = start_period + timedelta(days=6) except ValueError: raise ValidationError( {"title": ["Title should be in format %m-%Y or %w-%W-%Y"]}) data["date"] = end_period.strftime("%Y-%m-%d") data["key_word"] = data.pop("title__title") return super(ThemeCompanySdViewsSerializer, self).to_internal_value(data=data)
class AlertRuleTriggerActionSerializer(CamelSnakeModelSerializer): """ Serializer for creating/updating a trigger action. Required context: - `trigger`: The trigger related to this action. - `alert_rule`: The alert_rule related to this action. - `organization`: The organization related to this action. - `access`: An access object (from `request.access`) - `user`: The user from `request.user` """ id = serializers.IntegerField(required=False) type = serializers.CharField() target_type = serializers.CharField() sentry_app_config = serializers.JSONField(required=False) # array of dicts sentry_app_installation_uuid = serializers.CharField(required=False) class Meta: model = AlertRuleTriggerAction fields = [ "id", "type", "target_type", "target_identifier", "integration", "sentry_app", "sentry_app_config", "sentry_app_installation_uuid", ] extra_kwargs = { "target_identifier": { "required": True }, "target_display": { "required": False }, "integration": { "required": False, "allow_null": True }, "sentry_app": { "required": False, "allow_null": True }, "sentry_app_config": { "required": False, "allow_null": True }, "sentry_app_installation_uuid": { "required": False, "allow_null": True }, } def validate_type(self, type): if type not in STRING_TO_ACTION_TYPE: raise serializers.ValidationError( "Invalid type, valid values are [%s]" % ", ".join(STRING_TO_ACTION_TYPE.keys())) return STRING_TO_ACTION_TYPE[type] def validate_target_type(self, target_type): if target_type not in STRING_TO_ACTION_TARGET_TYPE: raise serializers.ValidationError( "Invalid targetType, valid values are [%s]" % ", ".join(STRING_TO_ACTION_TARGET_TYPE.keys())) return STRING_TO_ACTION_TARGET_TYPE[target_type] def validate(self, attrs): if ("type" in attrs) != ("target_type" in attrs) != ("target_identifier" in attrs): raise serializers.ValidationError( "type, targetType and targetIdentifier must be passed together" ) type = attrs.get("type") target_type = attrs.get("target_type") access = self.context["access"] identifier = attrs.get("target_identifier") if type is not None: type_info = AlertRuleTriggerAction.get_registered_type(type) if target_type not in type_info.supported_target_types: allowed_target_types = ",".join( ACTION_TARGET_TYPE_TO_STRING[type_name] for type_name in type_info.supported_target_types) raise serializers.ValidationError({ "target_type": "Invalid target type for %s. Valid types are [%s]" % (type_info.slug, allowed_target_types) }) if attrs.get("type") == AlertRuleTriggerAction.Type.EMAIL: if target_type == AlertRuleTriggerAction.TargetType.TEAM: try: team = Team.objects.get(id=identifier) except Team.DoesNotExist: raise serializers.ValidationError("Team does not exist") if not access.has_team(team): raise serializers.ValidationError("Team does not exist") elif target_type == AlertRuleTriggerAction.TargetType.USER: try: user = User.objects.get(id=identifier) except User.DoesNotExist: raise serializers.ValidationError("User does not exist") if not OrganizationMember.objects.filter( organization=self.context["organization"], user=user).exists(): raise serializers.ValidationError( "User does not belong to this organization") elif attrs.get("type") == AlertRuleTriggerAction.Type.SLACK: if not attrs.get("integration"): raise serializers.ValidationError( {"integration": "Integration must be provided for slack"}) elif attrs.get("type") == AlertRuleTriggerAction.Type.SENTRY_APP: if not attrs.get("sentry_app"): raise serializers.ValidationError({ "sentry_app": "SentryApp must be provided for sentry_app" }) if attrs.get("sentry_app_config"): if attrs.get("sentry_app_installation_uuid") is None: raise serializers.ValidationError({ "sentry_app": "Missing parameter: sentry_app_installation_uuid" }) try: install = SentryAppInstallation.objects.get( uuid=attrs.get("sentry_app_installation_uuid")) except SentryAppInstallation.DoesNotExist: raise serializers.ValidationError( {"sentry_app": "The installation does not exist."}) # Check response from creator and bubble up errors from providers as a ValidationError result = alert_rule_actions.AlertRuleActionCreator.run( install=install, fields=attrs.get("sentry_app_config"), ) if not result["success"]: raise serializers.ValidationError( {"sentry_app": result["message"]}) del attrs["sentry_app_installation_uuid"] attrs["use_async_lookup"] = self.context.get("use_async_lookup") attrs["input_channel_id"] = self.context.get("input_channel_id") should_validate_channel_id = self.context.get("validate_channel_id", True) # validate_channel_id is assumed to be true unless explicitly passed as false if attrs["input_channel_id"] and should_validate_channel_id: validate_channel_id(identifier, attrs["integration"].id, attrs["input_channel_id"]) return attrs def create(self, validated_data): try: action = create_alert_rule_trigger_action( trigger=self.context["trigger"], **validated_data) except InvalidTriggerActionError as e: raise serializers.ValidationError(force_text(e)) except ApiRateLimitedError as e: raise serializers.ValidationError(force_text(e)) else: analytics.record( "metric_alert_with_ui_component.created", user_id=getattr(self.context["user"], "id", None), alert_rule_id=getattr(self.context["alert_rule"], "id"), organization_id=getattr(self.context["organization"], "id"), ) return action def update(self, instance, validated_data): if "id" in validated_data: validated_data.pop("id") try: return update_alert_rule_trigger_action(instance, **validated_data) except InvalidTriggerActionError as e: raise serializers.ValidationError(force_text(e)) except ApiRateLimitedError as e: raise serializers.ValidationError(force_text(e))
class OrganizationSerializer(serializers.Serializer): name = serializers.CharField(max_length=64) slug = serializers.RegexField(r"^[a-z0-9_\-]+$", max_length=50) accountRateLimit = EmptyIntegerField( min_value=0, max_value=1000000, required=False, allow_null=True ) projectRateLimit = EmptyIntegerField( min_value=50, max_value=100, required=False, allow_null=True ) avatar = AvatarField(required=False, allow_null=True) avatarType = serializers.ChoiceField( choices=(("upload", "upload"), ("letter_avatar", "letter_avatar")), required=False, allow_null=True, ) openMembership = serializers.BooleanField(required=False) allowSharedIssues = serializers.BooleanField(required=False) enhancedPrivacy = serializers.BooleanField(required=False) dataScrubber = serializers.BooleanField(required=False) dataScrubberDefaults = serializers.BooleanField(required=False) sensitiveFields = ListField(child=serializers.CharField(), required=False) safeFields = ListField(child=serializers.CharField(), required=False) storeCrashReports = serializers.IntegerField(min_value=-1, max_value=20, required=False) attachmentsRole = serializers.CharField(required=True) scrubIPAddresses = serializers.BooleanField(required=False) scrapeJavaScript = serializers.BooleanField(required=False) isEarlyAdopter = serializers.BooleanField(required=False) require2FA = serializers.BooleanField(required=False) trustedRelays = ListField(child=serializers.CharField(), required=False) allowJoinRequests = serializers.BooleanField(required=False) @memoize def _has_legacy_rate_limits(self): org = self.context["organization"] return OrganizationOption.objects.filter( organization=org, key__in=LEGACY_RATE_LIMIT_OPTIONS ).exists() def _has_sso_enabled(self): org = self.context["organization"] return AuthProvider.objects.filter(organization=org).exists() def validate_slug(self, value): # Historically, the only check just made sure there was more than 1 # character for the slug, but since then, there are many slugs that # fit within this new imposed limit. We're not fixing existing, but # just preventing new bad values. if len(value) < 3: raise serializers.ValidationError( 'This slug "%s" is too short. Minimum of 3 characters.' % (value,) ) if value in RESERVED_ORGANIZATION_SLUGS: raise serializers.ValidationError( 'This slug "%s" is reserved and not allowed.' % (value,) ) qs = Organization.objects.filter(slug=value).exclude(id=self.context["organization"].id) if qs.exists(): raise serializers.ValidationError('The slug "%s" is already in use.' % (value,)) return value def validate_sensitiveFields(self, value): if value and not all(value): raise serializers.ValidationError("Empty values are not allowed.") return value def validate_safeFields(self, value): if value and not all(value): raise serializers.ValidationError("Empty values are not allowed.") return value def validate_attachmentsRole(self, value): try: roles.get(value) except KeyError: raise serializers.ValidationError("Invalid role") return value def validate_require2FA(self, value): user = self.context["user"] has_2fa = Authenticator.objects.user_has_2fa(user) if value and not has_2fa: raise serializers.ValidationError(ERR_NO_2FA) if value and self._has_sso_enabled(): raise serializers.ValidationError(ERR_SSO_ENABLED) return value def validate_trustedRelays(self, value): from sentry import features organization = self.context["organization"] request = self.context["request"] has_relays = features.has("organizations:relay", organization, actor=request.user) if not has_relays: raise serializers.ValidationError( "Organization does not have the relay feature enabled" ) return value def validate_accountRateLimit(self, value): if not self._has_legacy_rate_limits: raise serializers.ValidationError( "The accountRateLimit option cannot be configured for this organization" ) return value def validate_projectRateLimit(self, value): if not self._has_legacy_rate_limits: raise serializers.ValidationError( "The accountRateLimit option cannot be configured for this organization" ) return value def validate(self, attrs): attrs = super(OrganizationSerializer, self).validate(attrs) if attrs.get("avatarType") == "upload": has_existing_file = OrganizationAvatar.objects.filter( organization=self.context["organization"], file__isnull=False ).exists() if not has_existing_file and not attrs.get("avatar"): raise serializers.ValidationError( {"avatarType": "Cannot set avatarType to upload without avatar"} ) return attrs def save(self): org = self.context["organization"] changed_data = {} for key, option, type_, default_value in ORG_OPTIONS: if key not in self.initial_data: continue try: option_inst = OrganizationOption.objects.get(organization=org, key=option) except OrganizationOption.DoesNotExist: OrganizationOption.objects.set_value( organization=org, key=option, value=type_(self.initial_data[key]) ) if self.initial_data[key] != default_value: changed_data[key] = u"to {}".format(self.initial_data[key]) else: option_inst.value = self.initial_data[key] # check if ORG_OPTIONS changed if option_inst.has_changed("value"): old_val = option_inst.old_value("value") changed_data[key] = u"from {} to {}".format(old_val, option_inst.value) option_inst.save() if "openMembership" in self.initial_data: org.flags.allow_joinleave = self.initial_data["openMembership"] if "allowSharedIssues" in self.initial_data: org.flags.disable_shared_issues = not self.initial_data["allowSharedIssues"] if "enhancedPrivacy" in self.initial_data: org.flags.enhanced_privacy = self.initial_data["enhancedPrivacy"] if "isEarlyAdopter" in self.initial_data: org.flags.early_adopter = self.initial_data["isEarlyAdopter"] if "require2FA" in self.initial_data: org.flags.require_2fa = self.initial_data["require2FA"] if "name" in self.initial_data: org.name = self.initial_data["name"] if "slug" in self.initial_data: org.slug = self.initial_data["slug"] org_tracked_field = { "name": org.name, "slug": org.slug, "default_role": org.default_role, "flag_field": { "allow_joinleave": org.flags.allow_joinleave.is_set, "enhanced_privacy": org.flags.enhanced_privacy.is_set, "disable_shared_issues": org.flags.disable_shared_issues.is_set, "early_adopter": org.flags.early_adopter.is_set, "require_2fa": org.flags.require_2fa.is_set, }, } # check if fields changed for f, v in six.iteritems(org_tracked_field): if f != "flag_field": if org.has_changed(f): old_val = org.old_value(f) changed_data[f] = u"from {} to {}".format(old_val, v) else: # check if flag fields changed for f, v in six.iteritems(org_tracked_field["flag_field"]): if org.flag_has_changed(f): changed_data[f] = u"to {}".format(v) org.save() if "avatar" in self.initial_data or "avatarType" in self.initial_data: OrganizationAvatar.save_avatar( relation={"organization": org}, type=self.initial_data.get("avatarType", "upload"), avatar=self.initial_data.get("avatar"), filename=u"{}.png".format(org.slug), ) if "require2FA" in self.initial_data and self.initial_data["require2FA"] is True: org.handle_2fa_required(self.context["request"]) return org, changed_data
class BaseFileSerializer(JSONAPISerializer): filterable_fields = frozenset([ 'id', 'name', 'kind', 'path', 'materialized_path', 'size', 'provider', 'last_touched', 'tags', ]) id = IDField(source='_id', read_only=True) type = TypeField() guid = ser.SerializerMethodField(read_only=True, method_name='get_file_guid', help_text='OSF GUID for this file (if one has been assigned)') checkout = CheckoutField() name = ser.CharField(read_only=True, help_text='Display name used in the general user interface') kind = ser.CharField(read_only=True, help_text='Either folder or file') path = ser.CharField(read_only=True, help_text='The unique path used to reference this object') size = ser.SerializerMethodField(read_only=True, help_text='The size of this file at this version') provider = ser.CharField(read_only=True, help_text='The Add-on service this file originates from') materialized_path = ser.CharField( read_only=True, help_text='The Unix-style path of this object relative to the provider root') last_touched = VersionedDateTimeField(read_only=True, help_text='The last time this file had information fetched about it via the OSF') date_modified = ser.SerializerMethodField(read_only=True, help_text='Timestamp when the file was last modified') date_created = ser.SerializerMethodField(read_only=True, help_text='Timestamp when the file was created') extra = ser.SerializerMethodField(read_only=True, help_text='Additional metadata about this file') tags = JSONAPIListField(child=FileTagField(), required=False) current_user_can_comment = ser.SerializerMethodField(help_text='Whether the current user is allowed to post comments') current_version = ser.IntegerField(help_text='Latest file version', read_only=True, source='current_version_number') delete_allowed = ser.BooleanField(read_only=True, required=False) files = NodeFileHyperLinkField( related_view='nodes:node-files', related_view_kwargs={'node_id': '<target._id>', 'path': '<path>', 'provider': '<provider>'}, kind='folder' ) versions = NodeFileHyperLinkField( related_view='files:file-versions', related_view_kwargs={'file_id': '<_id>'}, kind='file' ) comments = FileCommentRelationshipField(related_view='nodes:node-comments', related_view_kwargs={'node_id': '<target._id>'}, related_meta={'unread': 'get_unread_comments_count'}, filter={'target': 'get_file_guid'} ) links = LinksField({ 'info': Link('files:file-detail', kwargs={'file_id': '<_id>'}), 'move': WaterbutlerLink(), 'upload': WaterbutlerLink(), 'delete': WaterbutlerLink(), 'download': 'get_download_link', 'new_folder': WaterbutlerLink(must_be_folder=True, kind='folder'), }) def get_download_link(self, obj): if obj.is_file: return get_file_download_link(obj, view_only=self.context['request'].query_params.get('view_only')) class Meta: type_ = 'files' def get_size(self, obj): if obj.versions.exists(): self.size = obj.versions.first().size return self.size return None def get_date_modified(self, obj): mod_dt = None if obj.provider == 'osfstorage' and obj.versions.exists(): # Each time an osfstorage file is added or uploaded, a new version object is created with its # date_created equal to the time of the update. The external_modified is the modified date # from the backend the file is stored on. This field refers to the modified date on osfstorage, # so prefer to use the created of the latest version. mod_dt = obj.versions.first().created elif obj.provider != 'osfstorage' and obj.history: mod_dt = obj.history[-1].get('modified', None) if self.context['request'].version >= '2.2' and obj.is_file and mod_dt: return datetime.strftime(mod_dt, '%Y-%m-%dT%H:%M:%S.%fZ') return mod_dt and mod_dt.replace(tzinfo=pytz.utc) def get_date_created(self, obj): creat_dt = None if obj.provider == 'osfstorage' and obj.versions.exists(): creat_dt = obj.versions.last().created elif obj.provider != 'osfstorage' and obj.history: # Non-osfstorage files don't store a created date, so instead get the modified date of the # earliest entry in the file history. creat_dt = obj.history[0].get('modified', None) if self.context['request'].version >= '2.2' and obj.is_file and creat_dt: return datetime.strftime(creat_dt, '%Y-%m-%dT%H:%M:%S.%fZ') return creat_dt and creat_dt.replace(tzinfo=pytz.utc) def get_extra(self, obj): metadata = {} if obj.provider == 'osfstorage' and obj.versions.exists(): metadata = obj.versions.first().metadata elif obj.provider != 'osfstorage' and obj.history: metadata = obj.history[-1].get('extra', {}) extras = {} extras['hashes'] = { # mimic waterbutler response 'md5': metadata.get('md5', None), 'sha256': metadata.get('sha256', None), } if obj.provider == 'osfstorage' and obj.is_file: extras['downloads'] = obj.get_download_count() return extras def get_current_user_can_comment(self, obj): user = self.context['request'].user auth = Auth(user if not user.is_anonymous else None) return obj.target.can_comment(auth) def get_unread_comments_count(self, obj): user = self.context['request'].user if user.is_anonymous: return 0 return Comment.find_n_unread(user=user, node=obj.target, page='files', root_id=obj.get_guid()._id) def user_id(self, obj): # NOTE: obj is the user here, the meta field for # Hyperlinks is weird if obj: return obj._id return None def update(self, instance, validated_data): assert isinstance(instance, BaseFileNode), 'Instance must be a BaseFileNode' if instance.provider != 'osfstorage' and 'tags' in validated_data: raise Conflict('File service provider {} does not support tags on the OSF.'.format(instance.provider)) auth = get_user_auth(self.context['request']) old_tags = set(instance.tags.values_list('name', flat=True)) if 'tags' in validated_data: current_tags = set(validated_data.pop('tags', [])) else: current_tags = set(old_tags) for new_tag in (current_tags - old_tags): instance.add_tag(new_tag, auth=auth) for deleted_tag in (old_tags - current_tags): instance.remove_tag(deleted_tag, auth=auth) for attr, value in validated_data.items(): if attr == 'checkout': user = self.context['request'].user instance.check_in_or_out(user, value) else: setattr(instance, attr, value) instance.save() return instance def is_valid(self, **kwargs): return super(BaseFileSerializer, self).is_valid(clean_html=False, **kwargs) def get_file_guid(self, obj): if obj: guid = obj.get_guid() if guid: return guid._id return None def get_absolute_url(self, obj): return api_v2_url('files/{}/'.format(obj._id))
class ProjectCodeOwnerSerializer(CamelSnakeModelSerializer): code_mapping_id = serializers.IntegerField(required=True) raw = serializers.CharField(required=True) organization_integration_id = serializers.IntegerField(required=False) class Meta: model = ProjectCodeOwners fields = ["raw", "code_mapping_id", "organization_integration_id"] def validate(self, attrs): # If it already exists, set default attrs with existing values if self.instance: attrs = { "raw": self.instance.raw, "code_mapping_id": self.instance.repository_project_path_config, **attrs, } if not attrs.get("raw", "").strip(): return attrs external_association_err = [] # Get list of team/user names from CODEOWNERS file teamnames, usernames, emails = parse_code_owners(attrs["raw"]) # Check if there exists Sentry users with the emails listed in CODEOWNERS user_emails = UserEmail.objects.filter(email__in=emails) user_emails_diff = self._validate_association(emails, user_emails, "emails") external_association_err.extend(user_emails_diff) # Check if the usernames have an association external_users = ExternalUser.objects.filter( external_name__in=usernames, organizationmember__organization=self.context["project"].organization, ) external_users_diff = self._validate_association(usernames, external_users, "usernames") external_association_err.extend(external_users_diff) # Check if the team names have an association external_teams = ExternalTeam.objects.filter( external_name__in=teamnames, team__organization=self.context["project"].organization, ) external_teams_diff = self._validate_association(teamnames, external_teams, "team names") external_association_err.extend(external_teams_diff) if len(external_association_err): raise serializers.ValidationError({"raw": "\n".join(external_association_err)}) # Convert CODEOWNERS into IssueOwner syntax users_dict = { user.external_name: user.organizationmember.user.email for user in external_users } teams_dict = {team.external_name: f"#{team.team.slug}" for team in external_teams} emails_dict = {email: email for email in emails} associations = {**users_dict, **teams_dict, **emails_dict} issue_owner_rules = convert_codeowners_syntax( attrs["raw"], associations, attrs["code_mapping_id"] ) # Convert IssueOwner syntax into schema syntax validated_data = ProjectOwnershipSerializer(context=self.context).validate( {"raw": issue_owner_rules} ) return {**validated_data, **attrs} def _validate_association(self, raw_items, associations, type): if type == "emails": # associations are UserEmail objects sentry_items = [item.email for item in associations] else: # associations can be ExternalUser or ExternalTeam objects sentry_items = [item.external_name for item in associations] diff = [item for item in raw_items if item not in sentry_items] if len(diff): return [ f'The following {type} do not have an association in Sentry: {", ".join(diff)}.' ] return [] def validate_code_mapping_id(self, code_mapping_id): try: return RepositoryProjectPathConfig.objects.get( id=code_mapping_id, project=self.context["project"] ) except RepositoryProjectPathConfig.DoesNotExist: raise serializers.ValidationError("This code mapping does not exist.") def create(self, validated_data): # Save projectcodeowners record repository_project_path_config = validated_data.pop("code_mapping_id", None) project = self.context["project"] return ProjectCodeOwners.objects.create( repository_project_path_config=repository_project_path_config, project=project, **validated_data, ) def update(self, instance, validated_data): if "id" in validated_data: validated_data.pop("id") for key, value in validated_data.items(): setattr(self.instance, key, value) self.instance.save() return self.instance
class SubmissionCountSerializer(serializers.Serializer): submission_count = serializers.IntegerField()
class BulkOperationSerializer(serializers.Serializer): id = serializers.IntegerField()
class LessonTrainingDirectionConstraintSerializer(serializers.Serializer): training_direction_id = serializers.IntegerField(required=False) id = serializers.IntegerField(required=False) lesson = serializers.IntegerField() day_of_week = serializers.IntegerField() remove = serializers.BooleanField(default=False)
class AppSerializer(serializers.ModelSerializer): app_type = serializers.ChoiceField( choices=amo.ADDON_WEBAPP_TYPES_LOOKUP.items(), read_only=True) author = serializers.CharField(source='developer_name', read_only=True) banner_message = TranslationSerializerField(read_only=True, source='geodata.banner_message') banner_regions = serializers.Field(source='geodata.banner_regions_slugs') categories = serializers.SlugRelatedField(source='categories', many=True, slug_field='slug', required=True, queryset=Category.objects.filter(type=amo.ADDON_WEBAPP)) content_ratings = serializers.SerializerMethodField('get_content_ratings') created = serializers.DateField(read_only=True) current_version = serializers.CharField( source='current_version.version', read_only=True) default_locale = serializers.CharField(read_only=True) device_types = SemiSerializerMethodField('get_device_types') description = TranslationSerializerField(required=False) homepage = TranslationSerializerField(required=False) icons = serializers.SerializerMethodField('get_icons') id = serializers.IntegerField(source='pk', required=False) is_packaged = serializers.BooleanField(read_only=True) manifest_url = serializers.CharField(source='get_manifest_url', read_only=True) name = TranslationSerializerField(required=False) payment_account = serializers.HyperlinkedRelatedField( view_name='payment-account-detail', source='app_payment_account', required=False) payment_required = serializers.SerializerMethodField( 'get_payment_required') premium_type = ReverseChoiceField( choices_dict=amo.ADDON_PREMIUM_API, required=False) previews = PreviewSerializer(many=True, required=False, source='all_previews') price = SemiSerializerMethodField('get_price') price_locale = serializers.SerializerMethodField('get_price_locale') privacy_policy = LargeTextField(view_name='app-privacy-policy-detail', required=False) public_stats = serializers.BooleanField(read_only=True) ratings = serializers.SerializerMethodField('get_ratings_aggregates') regions = RegionSerializer(read_only=True, source='get_regions') release_notes = TranslationSerializerField(read_only=True, source='current_version.releasenotes') resource_uri = serializers.HyperlinkedIdentityField(view_name='app-detail') slug = serializers.CharField(source='app_slug', required=False) status = serializers.IntegerField(read_only=True) support_email = TranslationSerializerField(required=False) support_url = TranslationSerializerField(required=False) supported_locales = serializers.SerializerMethodField( 'get_supported_locales') tags = serializers.SerializerMethodField('get_tags') upsell = serializers.SerializerMethodField('get_upsell') upsold = serializers.HyperlinkedRelatedField( view_name='app-detail', source='upsold.free', required=False, queryset=Webapp.objects.all()) user = serializers.SerializerMethodField('get_user_info') versions = serializers.SerializerMethodField('get_versions') weekly_downloads = serializers.SerializerMethodField( 'get_weekly_downloads') class Meta: model = Webapp fields = [ 'app_type', 'author', 'banner_message', 'banner_regions', 'categories', 'content_ratings', 'created', 'current_version', 'default_locale', 'description', 'device_types', 'homepage', 'icons', 'id', 'is_packaged', 'manifest_url', 'name', 'payment_account', 'payment_required', 'premium_type', 'previews', 'price', 'price_locale', 'privacy_policy', 'public_stats', 'release_notes', 'ratings', 'regions', 'resource_uri', 'slug', 'status', 'support_email', 'support_url', 'supported_locales', 'tags', 'upsell', 'upsold', 'user', 'versions', 'weekly_downloads'] def _get_region_id(self): request = self.context.get('request') REGION = getattr(request, 'REGION', None) return REGION.id if REGION else None def _get_region_slug(self): request = self.context.get('request') REGION = getattr(request, 'REGION', None) return REGION.slug if REGION else None def get_content_ratings(self, app): return filter_content_ratings_by_region({ 'ratings': app.get_content_ratings_by_body() or None, 'descriptors': app.get_descriptors() or None, 'interactive_elements': app.get_interactives() or None, 'regions': mkt.regions.REGION_TO_RATINGS_BODY() }, region=self._get_region_slug()) def get_icons(self, app): return dict([(icon_size, app.get_icon_url(icon_size)) for icon_size in (16, 48, 64, 128)]) def get_payment_required(self, app): if app.has_premium(): tier = app.get_tier() return bool(tier and tier.price) return False def get_price(self, app): if app.has_premium(): region = self._get_region_id() if region in app.get_price_region_ids(): return app.get_price(region=region) return None def get_price_locale(self, app): if app.has_premium(): region = self._get_region_id() if region in app.get_price_region_ids(): return app.get_price_locale(region=region) return None def get_ratings_aggregates(self, app): return {'average': app.average_rating, 'count': app.total_reviews} def get_supported_locales(self, app): locs = getattr(app.current_version, 'supported_locales', '') if locs: return locs.split(',') if isinstance(locs, basestring) else locs else: return [] def get_tags(self, app): return [t.tag_text for t in app.tags.all()] def get_upsell(self, app): upsell = False if app.upsell: upsell = app.upsell.premium # Only return the upsell app if it's public and we are not in an # excluded region. if (upsell and upsell.is_public() and self._get_region_id() not in upsell.get_excluded_region_ids()): return { 'id': upsell.id, 'app_slug': upsell.app_slug, 'icon_url': upsell.get_icon_url(128), 'name': unicode(upsell.name), 'resource_uri': reverse('app-detail', kwargs={'pk': upsell.pk}) } else: return False def get_user_info(self, app): user = getattr(self.context.get('request'), 'amo_user', None) if user: return { 'developed': app.addonuser_set.filter( user=user, role=amo.AUTHOR_ROLE_OWNER).exists(), 'installed': app.has_installed(user), 'purchased': app.pk in user.purchase_ids(), } def get_versions(self, app): # Disable transforms, we only need two fields: version and pk. # Unfortunately, cache-machine gets in the way so we can't use .only() # (.no_transforms() is ignored, defeating the purpose), and we can't use # .values() / .values_list() because those aren't cached :( return dict((v.version, reverse('version-detail', kwargs={'pk': v.pk})) for v in app.versions.all().no_transforms()) def get_weekly_downloads(self, app): if app.public_stats: return app.weekly_downloads def validate_categories(self, attrs, source): if not attrs.get('categories'): raise serializers.ValidationError('This field is required.') set_categories = set(attrs[source]) total = len(set_categories) max_cat = amo.MAX_CATEGORIES if total > max_cat: # L10n: {0} is the number of categories. raise serializers.ValidationError(ngettext( 'You can have only {0} category.', 'You can have only {0} categories.', max_cat).format(max_cat)) return attrs def get_device_types(self, app): with no_translation(): return [n.api_name for n in app.device_types] def save_device_types(self, obj, new_types): new_types = [amo.DEVICE_LOOKUP[d].id for d in new_types] old_types = [x.id for x in obj.device_types] added_devices = set(new_types) - set(old_types) removed_devices = set(old_types) - set(new_types) for d in added_devices: obj.addondevicetype_set.create(device_type=d) for d in removed_devices: obj.addondevicetype_set.filter(device_type=d).delete() # Send app to re-review queue if public and new devices are added. if added_devices and obj.status in amo.WEBAPPS_APPROVED_STATUSES: mark_for_rereview(obj, added_devices, removed_devices) def save_categories(self, obj, categories): before = set(obj.categories.values_list('id', flat=True)) # Add new categories. to_add = set(c.id for c in categories) - before for c in to_add: AddonCategory.objects.create(addon=obj, category_id=c) # Remove old categories. to_remove = before - set(categories) for c in to_remove: obj.addoncategory_set.filter(category=c).delete() def save_upsold(self, obj, upsold): current_upsell = obj.upsold if upsold and upsold != obj.upsold.free: if not current_upsell: log.debug('[1@%s] Creating app upsell' % obj.pk) current_upsell = AddonUpsell(premium=obj) current_upsell.free = upsold current_upsell.save() elif current_upsell: # We're deleting the upsell. log.debug('[1@%s] Deleting the app upsell' % obj.pk) current_upsell.delete() def save_price(self, obj, price): premium = obj.premium if not premium: premium = AddonPremium() premium.addon = obj premium.price = Price.objects.active().get(price=price) premium.save() def validate_device_types(self, attrs, source): if attrs.get('device_types') is None: raise serializers.ValidationError('This field is required.') for v in attrs['device_types']: if v not in amo.DEVICE_LOOKUP.keys(): raise serializers.ValidationError( str(v) + ' is not one of the available choices.') return attrs def validate_price(self, attrs, source): if attrs.get('premium_type', None) not in (amo.ADDON_FREE, amo.ADDON_FREE_INAPP): valid_prices = Price.objects.exclude( price='0.00').values_list('price', flat=True) price = attrs.get('price') if not (price and Decimal(price) in valid_prices): raise serializers.ValidationError( 'Premium app specified without a valid price. Price can be' ' one of %s.' % (', '.join('"%s"' % str(p) for p in valid_prices),)) return attrs def restore_object(self, attrs, instance=None): # restore_object creates or updates a model instance, during # input validation. extras = [] # Upsell bits are handled here because we need to remove it # from the attrs dict before deserializing. upsold = attrs.pop('upsold.free', None) if upsold is not None: extras.append((self.save_upsold, upsold)) price = attrs.pop('price', None) if price is not None: extras.append((self.save_price, price)) device_types = attrs['device_types'] if device_types: extras.append((self.save_device_types, device_types)) del attrs['device_types'] if attrs.get('app_payment_account') is None: attrs.pop('app_payment_account') instance = super(AppSerializer, self).restore_object( attrs, instance=instance) for f, v in extras: f(instance, v) return instance def save_object(self, obj, **kwargs): # this only gets called if validation succeeds. m2m = getattr(obj, '_m2m_data', {}) cats = m2m.pop('categories', None) super(AppSerializer, self).save_object(obj, **kwargs) # Categories are handled here because we can't look up # existing ones until the initial save is done. self.save_categories(obj, cats)
class RackSerializer(PrimaryModelSerializer): url = serializers.HyperlinkedIdentityField( view_name='dcim-api:rack-detail') site = NestedSiteSerializer() location = NestedLocationSerializer(required=False, allow_null=True, default=None) tenant = NestedTenantSerializer(required=False, allow_null=True) status = ChoiceField(choices=RackStatusChoices, required=False) role = NestedRackRoleSerializer(required=False, allow_null=True) type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False) width = ChoiceField(choices=RackWidthChoices, required=False) outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False) device_count = serializers.IntegerField(read_only=True) powerfeed_count = serializers.IntegerField(read_only=True) class Meta: model = Rack fields = [ 'id', 'url', 'display', 'name', 'facility_id', 'site', 'location', 'tenant', 'status', 'role', 'serial', 'asset_tag', 'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'powerfeed_count', ] # Omit the UniqueTogetherValidator that would be automatically added to validate (location, facility_id). This # prevents facility_id from being interpreted as a required field. validators = [ UniqueTogetherValidator(queryset=Rack.objects.all(), fields=('location', 'name')) ] def validate(self, data): # Validate uniqueness of (location, facility_id) since we omitted the automatically-created validator from Meta. if data.get('facility_id', None): validator = UniqueTogetherValidator(queryset=Rack.objects.all(), fields=('location', 'facility_id')) validator(data, self) # Enforce model validation super().validate(data) return data
class QuizMarkSerializer(serializers.ModelSerializer): mark = serializers.IntegerField(max_value=200, min_value=0) class Meta: model = Language fields = ['mark']
class DataStreamSerializer(ResourceSerializer): title = serializers.CharField(help_text=_(u'Título del conjunto de datos')) description = serializers.CharField( help_text=_(u'Descripción del conjunto de datos')) category = serializers.ChoiceField( tuple(), help_text= _(u'Nombre de la categoría para clasificar los recursos. Debe coincidir con alguna de las categorías de la cuenta' )) notes = serializers.CharField( required=False, allow_null=True, help_text=_(u'Texto de la nota del conjunto de datos')) table_id = serializers.IntegerField( required=False, allow_null=True, default=0, help_text=_( u'Indice de la tabla en el conjunto de datos, comenzando de cero.') ) header_row = serializers.IntegerField( required=False, allow_null=True, help_text= _(u'Indice de la fila a usar como cabecera de la tabla comenzando de cero. Por defecto es vacio' )) dataset = serializers.CharField( required=False, help_text=_(u'GUID del conjunto de datos asociado a la vista')) def __init__(self, *args, **kwargs): super(DataStreamSerializer, self).__init__(*args, **kwargs) self.fields['category'] = serializers.ChoiceField( self.getAccountCategoriesChoices(), help_text=self.fields['category'].help_text) def to_representation(self, obj): answer = super(DataStreamSerializer, self).to_representation(obj) self.tryKeysOnDict(answer, 'parameters', obj, ['parameters']) return answer def validate(self, data): guid = data.pop('dataset', None) if guid: try: self.dataset = DatasetDBDAO().get( self.context['request'].auth['language'], guid=guid, published=False) data['dataset'] = Dataset.objects.get( id=self.dataset['dataset_id']) except ObjectDoesNotExist: # TODO: mejorar errores raise exceptions.ValidationError( {'dataset': 'Dataset no existe'}) if data['dataset'].last_revision.impl_type not in DATASTREAM_IMPL_VALID_CHOICES: # TODO: mejorar errores raise exceptions.ValidationError({ 'dataset': 'El tipo de archivo no permite creacion de vistas' }) if 'table_id' in data: table_id = data.pop('table_id') data['select_statement'] = SelectStatementBuilder().build( table_id) data['data_source'] = DataSourceBuilder().build( table_id, data['dataset'].last_revision_id, 'microsites') if 'category' in data and data['category']: data['category'] = self.getCategory(data['category']).id data['status'] = StatusChoices.PENDING_REVIEW data['language'] = self.context['request'].auth['language'] return data def getDao(self, datastream_revision): return DataStreamDBDAO().get( datastream_revision_id=datastream_revision.id, language=self.context['request'].auth['language'], published=False) def create(self, validated_data): if 'dataset' not in validated_data: raise exceptions.ValidationError({'dataset': 'No hay dataset'}) return self.getDao( DatastreamLifeCycleManager( self.context['request'].user).create(**validated_data)) def update(self, instance, validated_data): lcycle = DatastreamLifeCycleManager( self.context['request'].user, datastream_id=instance['datastream_id']) instance.update(validated_data) instance.pop('datastream', None) instance.pop('dataset', None) instance.pop('user', None) instance.pop('status', None) instance.pop('parameters', None) if 'category' not in instance: instance['category'] = instance['category_id'] return self.getDao( lcycle.edit(changed_fields=validated_data.keys(), **instance))
class SwSerializer(serializers.Serializer): BargainDate = serializers.IntegerField(required=False) PB = serializers.FloatField(read_only=True) PE = serializers.FloatField(read_only=True)
class ProductStatSerializer(serializers.Serializer): stats = serializers.DictField( child=serializers.ListField( child=serializers.IntegerField() ) )
class StockSerializer(serializers.Serializer): code = serializers.CharField(required=False) close = serializers.FloatField(read_only=True) volume = serializers.FloatField(read_only=True) timestamp = serializers.IntegerField(read_only=True) turn_rate = serializers.FloatField(read_only=True)
class MarkNotificationsAsReadSerializer(serializers.Serializer): topic = serializers.IntegerField(required=False, allow_null=True)
class LevelSerializer(OptionFieldsFilter, serializers.ModelSerializer): ''' @class LevelSerializer @brief Serializer class for Level ''' member_count = serializers.IntegerField(read_only=True) name = serializers.CharField(max_length=255) remit_limit = serializers.CharField(required=False, max_length=255, allow_null=True) online_limit = serializers.CharField(required=False, max_length=255, allow_null=True) withdraw_limit = serializers.CharField(required=False, max_length=255, allow_null=True) # withdraw_fee = serializers.FloatField() withdraw_fee = serializers.CharField(max_length=100) reg_present = serializers.CharField(required=False, max_length=100, allow_null=True) remit_check = serializers.CharField(max_length=100, allow_null=True) service_rate = serializers.IntegerField() memo = serializers.CharField(required=False, allow_blank=True) status = serializers.IntegerField(default=1, allow_null=True) cdt_deposit_num = serializers.IntegerField(required=False, allow_null=True) cdt_deposit_amount = serializers.IntegerField(required=False, allow_null=True) cdt_deposit_max = serializers.IntegerField(required=False, allow_null=True) cdt_withdraw_num = serializers.IntegerField(required=False, allow_null=True) cdt_withdraw_amount = serializers.IntegerField(required=False, allow_null=True) remit_discounts = DiscountSerializer(required=False, source='level_remit_discount', many=True) online_discounts = DiscountSerializer(required=False, source='level_online_discount', many=True) __fields_to_validate = [ 'remit_limit', 'online_limit', 'withdraw_limit', 'withdraw_fee', 'reg_present', 'remit_check', ] class Meta: model = Level depth = 2 fields = ( 'member_count', 'id', 'name', 'remit_limit', 'online_limit', 'withdraw_limit', 'withdraw_fee', 'reg_present', 'remit_check', 'service_rate', 'memo', 'status', 'cdt_deposit_num', 'cdt_deposit_amount', 'cdt_deposit_max', 'cdt_withdraw_num', 'cdt_withdraw_amount', 'remit_discounts', 'online_discounts',) def to_internal_value(self, data): ret = super(LevelSerializer, self).to_internal_value(data) remit_discount = data.get('remit_discounts') online_discount = data.get('online_discounts') if remit_discount: ret['level_remit_discount'] = remit_discount if online_discount: ret['level_online_discount'] = online_discount return ret def validate(self, data): ''' @fn validate @brief Validates the data of the serializer. Specified field names needs to be a string convertible to python dictionary in order to be valid. ''' validated_data = dict() try: for key, value in data.iteritems(): if key in self.__fields_to_validate: # check if can be converted to dictionary if ast.literal_eval(value): pass # value is a valid string dictionary validated_data[key] = value except: raise serializers.ValidationError('Invalid data') return validated_data def create(self, validated_data): ''' ''' remit_discount = validated_data.get('level_remit_discount') online_discount = validated_data.get('level_online_discount') validated_data.pop('level_remit_discount', None) validated_data.pop('level_online_discount', None) level = Level(**validated_data) level.save() if remit_discount: self.__create_update_discount(level.level_remit_discount, remit_discount) if online_discount: self.__create_update_discount(level.level_online_discount, online_discount) level.save() return level def update(self, instance, validated_data): ''' ''' remit_discount = validated_data.get('level_remit_discount') online_discount = validated_data.get('level_online_discount') validated_data.pop('level_remit_discount', None) validated_data.pop('level_online_discount', None) for key, val in validated_data.iteritems(): setattr(instance, key, val) instance.save() if remit_discount: self.__create_update_discount(instance.level_remit_discount, remit_discount) if online_discount: self.__create_update_discount(instance.level_online_discount, online_discount) instance.save() return instance def __create_update_discount(self, instance, discount_details={}): ''' @fn __create_update_discount @brief Creates or updates discount details then adds the discount to the given level. ''' # clear the relationship for the level discount instance instance.clear() # process new relationships for discount in discount_details: # check if every field exists vailded = [(key in discount and discount.get(key) != '' ) for key in ['rate', 'check_rate', 'threshold']] if False in vailded: continue # check if discout had id if not discount.get('id'): # create discount discount_inst = instance.create(**discount) discount_inst.save() continue # update existing discount to_update = Discount.objects.get(pk=discount.get('id')) for key, value in discount.iteritems(): setattr(to_update, key, value) to_update.save() # add to level instance.add(to_update) return def to_representation(self, instance): ''' ''' request = self.context['request'] ret = super(LevelSerializer, self).to_representation(instance) to_display = collections.OrderedDict() for key, val in ret.iteritems(): if key in self.__fields_to_validate: val = collections.OrderedDict(ast.literal_eval(val)) to_display[key] = val return to_display