class TrackSerializer(serializers.Serializer): track = serializers.FileField(use_url=False)
class BadgeInstanceSerializerV1(OriginalJsonSerializerMixin, serializers.Serializer): created_at = DateTimeWithUtcZAtEndField(read_only=True, default_timezone=pytz.utc) created_by = BadgeUserIdentifierFieldV1(read_only=True) slug = serializers.CharField(max_length=255, read_only=True, source='entity_id') image = serializers.FileField(read_only=True) # use_url=True, might be necessary email = serializers.EmailField(max_length=1024, required=False, write_only=True) recipient_identifier = serializers.CharField(max_length=1024, required=False) recipient_type = serializers.CharField(default=RECIPIENT_TYPE_EMAIL) allow_uppercase = serializers.BooleanField(default=False, required=False, write_only=True) evidence = serializers.URLField(write_only=True, required=False, allow_blank=True, max_length=1024) narrative = MarkdownCharField(required=False, allow_blank=True, allow_null=True) evidence_items = EvidenceItemSerializer(many=True, required=False) revoked = HumanReadableBooleanField(read_only=True) revocation_reason = serializers.CharField(read_only=True) expires = DateTimeWithUtcZAtEndField(source='expires_at', required=False, allow_null=True, default_timezone=pytz.utc) create_notification = HumanReadableBooleanField(write_only=True, required=False, default=False) allow_duplicate_awards = serializers.BooleanField(write_only=True, required=False, default=True) hashed = serializers.NullBooleanField(default=None, required=False) extensions = serializers.DictField(source='extension_items', required=False, validators=[BadgeExtensionValidator()]) class Meta: apispec_definition = ('Assertion', {}) def validate(self, data): recipient_type = data.get('recipient_type') if data.get('recipient_identifier') and data.get('email') is None: if recipient_type == RECIPIENT_TYPE_EMAIL: recipient_validator = EmailValidator() elif recipient_type in (RECIPIENT_TYPE_URL, RECIPIENT_TYPE_ID): recipient_validator = URLValidator() else: recipient_validator = TelephoneValidator() try: recipient_validator(data['recipient_identifier']) except DjangoValidationError as e: raise serializers.ValidationError(e.message) elif data.get('email') and data.get('recipient_identifier') is None: data['recipient_identifier'] = data.get('email') allow_duplicate_awards = data.pop('allow_duplicate_awards') if allow_duplicate_awards is False and self.context.get('badgeclass') is not None: previous_awards = BadgeInstance.objects.filter( recipient_identifier=data['recipient_identifier'], badgeclass=self.context['badgeclass'] ).filter( Q(expires_at__isnull=True) | Q(expires_at__lt=timezone.now()) ) if previous_awards.exists(): raise serializers.ValidationError( "A previous award of this badge already exists for this recipient.") hashed = data.get('hashed', None) if hashed is None: if recipient_type in (RECIPIENT_TYPE_URL, RECIPIENT_TYPE_ID): data['hashed'] = False else: data['hashed'] = True return data def validate_narrative(self, data): if data is None or data == "": return None else: return data def to_representation(self, instance): representation = super(BadgeInstanceSerializerV1, self).to_representation(instance) representation['json'] = instance.get_json(obi_version="1_1", use_canonical_id=True) if self.context.get('include_issuer', False): representation['issuer'] = IssuerSerializerV1(instance.cached_badgeclass.cached_issuer).data else: representation['issuer'] = OriginSetting.HTTP+reverse('issuer_json', kwargs={'entity_id': instance.cached_issuer.entity_id}) if self.context.get('include_badge_class', False): representation['badge_class'] = BadgeClassSerializerV1(instance.cached_badgeclass, context=self.context).data else: representation['badge_class'] = OriginSetting.HTTP+reverse('badgeclass_json', kwargs={'entity_id': instance.cached_badgeclass.entity_id}) representation['public_url'] = OriginSetting.HTTP+reverse('badgeinstance_json', kwargs={'entity_id': instance.entity_id}) return representation def create(self, validated_data): """ Requires self.context to include request (with authenticated request.user) and badgeclass: issuer.models.BadgeClass. """ evidence_items = [] # ob1 evidence url evidence_url = validated_data.get('evidence') if evidence_url: evidence_items.append({'evidence_url': evidence_url}) # ob2 evidence items submitted_items = validated_data.get('evidence_items') if submitted_items: evidence_items.extend(submitted_items) try: return self.context.get('badgeclass').issue( recipient_id=validated_data.get('recipient_identifier'), narrative=validated_data.get('narrative'), evidence=evidence_items, notify=validated_data.get('create_notification'), created_by=self.context.get('request').user, allow_uppercase=validated_data.get('allow_uppercase'), recipient_type=validated_data.get('recipient_type', RECIPIENT_TYPE_EMAIL), badgr_app=BadgrApp.objects.get_current(self.context.get('request')), expires_at=validated_data.get('expires_at', None), extensions=validated_data.get('extension_items', None) ) except DjangoValidationError as e: raise serializers.ValidationError(e.message) def update(self, instance, validated_data): updateable_fields = [ 'evidence_items', 'expires_at', 'extension_items', 'hashed', 'narrative', 'recipient_identifier', 'recipient_type' ] for field_name in updateable_fields: if field_name in validated_data: setattr(instance, field_name, validated_data.get(field_name)) instance.rebake(save=False) instance.save() return instance
class PaidSerializer(serializers.Serializer): date = serializers.DateField(required=True) proof = serializers.FileField(required=False)
class BadgeInstanceSerializerV1(OriginalJsonSerializerMixin, serializers.Serializer): created_at = serializers.DateTimeField(read_only=True) created_by = BadgeUserIdentifierFieldV1(read_only=True) slug = serializers.CharField(max_length=255, read_only=True, source='entity_id') image = serializers.FileField( read_only=True) # use_url=True, might be necessary email = serializers.EmailField(max_length=1024, required=False, write_only=True) recipient_identifier = serializers.CharField(max_length=1024, required=False) recipient_type = serializers.CharField( default=BadgeInstance.RECIPIENT_TYPE_EMAIL) allow_uppercase = serializers.BooleanField(default=False, required=False, write_only=True) evidence = serializers.URLField(write_only=True, required=False, allow_blank=True, max_length=1024) narrative = MarkdownCharField(required=False, allow_blank=True, allow_null=True) evidence_items = EvidenceItemSerializer(many=True, required=False) revoked = HumanReadableBooleanField(read_only=True) revocation_reason = serializers.CharField(read_only=True) expires = serializers.DateTimeField(source='expires_at', required=False, allow_null=True) create_notification = HumanReadableBooleanField(write_only=True, required=False, default=False) hashed = serializers.NullBooleanField(default=None, required=False) extensions = serializers.DictField(source='extension_items', required=False, validators=[BadgeExtensionValidator()]) class Meta: apispec_definition = ('Assertion', {}) def validate(self, data): if data.get('email') and not data.get('recipient_identifier'): data['recipient_identifier'] = data.get('email') hashed = data.get('hashed', None) if hashed is None: recipient_type = data.get('recipient_type') if recipient_type in (BadgeInstance.RECIPIENT_TYPE_URL, BadgeInstance.RECIPIENT_TYPE_ID): data['hashed'] = False else: data['hashed'] = True return data def validate_narrative(self, data): if data is None or data == "": return None else: return data def to_representation(self, instance): # if self.context.get('extended_json'): # self.fields['json'] = V1InstanceSerializer(source='extended_json') representation = super(BadgeInstanceSerializerV1, self).to_representation(instance) representation['json'] = instance.get_json(obi_version="1_1", use_canonical_id=True) if self.context.get('include_issuer', False): representation['issuer'] = IssuerSerializerV1( instance.cached_badgeclass.cached_issuer).data else: representation['issuer'] = OriginSetting.HTTP + reverse( 'issuer_json', kwargs={'entity_id': instance.cached_issuer.entity_id}) if self.context.get('include_badge_class', False): representation['badge_class'] = BadgeClassSerializerV1( instance.cached_badgeclass, context=self.context).data else: representation['badge_class'] = OriginSetting.HTTP + reverse( 'badgeclass_json', kwargs={'entity_id': instance.cached_badgeclass.entity_id}) representation['public_url'] = OriginSetting.HTTP + reverse( 'badgeinstance_json', kwargs={'entity_id': instance.entity_id}) if apps.is_installed('badgebook'): try: from badgebook.models import BadgeObjectiveAward from badgebook.serializers import BadgeObjectiveAwardSerializer try: award = BadgeObjectiveAward.cached.get( badge_instance_id=instance.id) except BadgeObjectiveAward.DoesNotExist: representation['award'] = None else: representation['award'] = BadgeObjectiveAwardSerializer( award).data except ImportError: pass return representation def create(self, validated_data): """ Requires self.context to include request (with authenticated request.user) and badgeclass: issuer.models.BadgeClass. """ evidence_items = [] # ob1 evidence url evidence_url = validated_data.get('evidence') if evidence_url: evidence_items.append({'evidence_url': evidence_url}) # ob2 evidence items submitted_items = validated_data.get('evidence_items') if submitted_items: evidence_items.extend(submitted_items) return self.context.get('badgeclass').issue( recipient_id=validated_data.get('recipient_identifier'), narrative=validated_data.get('narrative'), evidence=evidence_items, notify=validated_data.get('create_notification'), created_by=self.context.get('request').user, allow_uppercase=validated_data.get('allow_uppercase'), recipient_type=validated_data.get( 'recipient_type', BadgeInstance.RECIPIENT_TYPE_EMAIL), badgr_app=BadgrApp.objects.get_current( self.context.get('request')), expires_at=validated_data.get('expires_at', None), extensions=validated_data.get('extension_items', None)) def update(self, instance, validated_data): updateable_fields = [ 'evidence_items', 'expires_at', 'extension_items', 'hashed', 'issued_on', 'narrative', 'recipient_identifier', 'recipient_type' ] for field_name in updateable_fields: if field_name in validated_data: setattr(instance, field_name, validated_data.get(field_name)) instance.rebake(save=False) instance.save() return instance
class HtmlFileInputSerializer(serializers.Serializer): file = serializers.FileField()
class ResourceFileValidator(serializers.Serializer): file = serializers.FileField() @swagger_serializer_method(serializer_or_field=file) def get_file(self, obj): return ResourceFileValidator().data
class BrandsSerializer(serializers.ModelSerializer): logo = serializers.FileField('logo.url') class Meta: model = Brand fields = '__all__'
class ResumableUploadSerializer(serializers.Serializer): """ resumable upload serializer """ batch_id = serializers.CharField( required=True, allow_blank=False, allow_null=False, max_length=36, error_messages={ 'required': 'Batch id is required', 'null': 'Batch id should not be null', 'blank': 'Batch id should not be blank', 'max_length': 'Batch id should not be greater than 36 characters', }) resumable_chunk_number = serializers.IntegerField( error_messages={ 'required': 'Resumable chunk number is required', 'blank': 'Resumable chunk number is required', 'null': 'Resumable chunk number is required', }) resumable_chunk_size = serializers.IntegerField( error_messages={ 'required': 'Resumable chunk size is required', 'blank': 'Resumable chunk size is required', 'null': 'Resumable chunk size is required', }) resumable_identifier = serializers.CharField( max_length=254, error_messages={ 'max_length': 'Resumable identifier should not be greater than 254'\ 'characters', 'required': 'Resumable identifier is required', 'blank': 'Resumable identifier is required', 'null': 'Resumable identifier is required', }) resumable_total_size = serializers.IntegerField( error_messages={ 'required': 'Resumable total size is required', 'blank': 'Resumable total size is required', 'null': 'Resumable total size is required', }) resumable_current_chunk_size = serializers.IntegerField( error_messages={ 'required': 'Resumable current chunk size is required', 'blank': 'Resumable current chunk size is required', 'null': 'Resumable current chunk size is required', }) resumable_filename = serializers.CharField( error_messages={ 'required': 'Resumable filename is required', 'blank': 'Resumable filename is required', 'null': 'Resumable filename is required', }) resumable_total_chunks = serializers.IntegerField( error_messages={ 'required': 'Resumable total chunks is required', 'blank': 'Resumable total chunks is required', 'null': 'Resumable total chunks is required', }) file = serializers.FileField( error_messages={ 'required': 'File is required', 'blank': 'File is required', 'null': 'File is required', }, style={'input_type': 'file'} ) def validate_batch_id(self, batch_id): """ validate batch id """ if not self.batch_instance: raise serializers.ValidationError('Batch uuid does not exist') return batch_id @property def batch_instance(self): """ Batch instance """ request = self.context.get('request') return Batch.objects.find_by_uuid(request.data.get('batch_id')) def get_or_create_upload_from_request(self, request): """ get or create upload from request """ name = request.data['resumable_filename'] file_id = request.data['resumable_identifier'] instance, _ = Upload.objects.get_or_create( user=request.user, file_id=file_id, batch=self.batch_instance, defaults={'name': name} ) return instance, _ def save(self): """ save """ request = self.context.get('request', None) if self.is_test_request(request): return self.check_chunk_status(request) try: upload, created = self.consume(request) except AssertionError as err: LOG.exception(err) return { 'status': 'ERROR', 'error_message': "Uploaded size > total size.", 'error_type': 'ApiError' } except Exception as err: upload = Upload.objects.get( batch__uuid=request.data.get('batch_id'), user=request.user, file_id=request.data.get('resumable_identifier')) upload.delete() return {'status': 'ERROR', 'error_message': str(err), 'error_type': 'ApiError'} return { 'status':'OK', 'created': created, 'upload': UploadShortSerializer(upload).data } @staticmethod def check_chunk_status(request): """ This always return HTTP 204 """ if False: return HttpResponse(status=200) return HttpResponse(status=204) @staticmethod def is_test_request(request): """ is test request """ return request.method == 'GET' def seek(self, request, f): """ seek """ chunk_size = int(request.data['resumable_chunk_size']) offset = (int(request.data['resumable_chunk_number']) - 1) * chunk_size LOG.debug('seking chunk, size:%s offset:%s', chunk_size, offset) f.seek(offset) assert f.tell() == offset return f def consume(self, request, **kwargs): """ consume """ upload_instance, _ = self.get_or_create_upload_from_request(request) uploaded_file = None if request.data.get('file', None): uploaded_file = request.data['file'] elif request.FILES: uploaded_file = request.FILES['file'] if uploaded_file: with self.seek(request, upload_instance.open()) as file_object: data = uploaded_file.read() file_object.write(data) resumable_chunk_number = request.data['resumable_chunk_number'] resumable_chunk_size = request.data['resumable_chunk_size'] resumable_current_chunk_size = request.data['resumable_current_chunk_size'] resumable_total_size = request.data['resumable_total_size'] offset = (int(resumable_chunk_number) - 1) * int(resumable_chunk_size) uploaded_size = offset + int(resumable_current_chunk_size) total_size = int(resumable_total_size) assert uploaded_size <= total_size uploaded_data = { 'chunk_number': resumable_chunk_number, 'uploaded_size': uploaded_size, 'uploaded_at': timezone.now().strftime('%Y-%m-%d %H:%M:%S %Z') } upload_instance.update_chunks_data(uploaded_data) if uploaded_size == total_size: upload_instance.content_type = upload_instance.c_type upload_instance.valid = True upload_instance.save() notification_task.uploaded.apply_async([upload_instance, request.get_host()]) return upload_instance, True return upload_instance, False
class FormDocumentDetailSerializer(ModelSerializer): """ FormDocumentDetailSerializer used to get details of Form """ uploaded_document = serializers.FileField(write_only=True, required=False) assets_urls = serializers.SerializerMethodField() is_access_code_protected = serializers.BooleanField(read_only=True) form_data = serializers.SerializerMethodField() document_mapping = serializers.SerializerMethodField() subdomain = serializers.CharField(source='owner.site.domain', read_only=True) class Meta: model = FormDocumentTemplate fields = ( 'id', 'title', 'slug', 'status', 'uploaded_document', 'form_data', 'form_config', 'document_mapping', 'assets_urls', 'is_access_code_protected', 'subdomain', ) def get_assets_urls(self, instance): if self._is_access_code_verified(instance): return map( lambda x: { # todo: Unit tests # This needs absolute uri, as our frontend server and backend server uses different port # Without absolute uri, the requests will be send to front-end address while it should # be in the backend 'url': self.context['request'].build_absolute_uri(x.image. url), 'width': x.cached_image_width, 'height': x.cached_image_height, }, instance.form_assets.all()) else: return None def _is_access_code_verified(self, instance): if self.instance.is_access_code_protected(): user = CurrentUserDefault() if getattr(user, 'id', None) == instance.owner.id: return True if self.context['request'].query_params.get( 'access_code') == instance.access_code: return True else: return False else: return True def get_form_data(self, instance): if self._is_access_code_verified(instance): return instance.form_data return None def get_document_mapping(self, instance): if self._is_access_code_verified(instance): return instance.document_mapping return None
class LsitExploEviGCMSTestFileSerializer(serializers.Serializer): # 用于接收多个文件 GCMSs = serializers.ListField(child=serializers.FileField( max_length=100000, allow_empty_file=False, use_url=True), write_only=True) #用于接收外键,GCMSTestFile的外键也是GCMS,AverFile只是用来取平均的 exploEviGCMS = serializers.IntegerField(required=True, write_only=True) # 保证Id只是我们内部维护的 exploEviId = serializers.IntegerField(read_only=True, ) # type = serializers.CharField(read_only= True,max_length=20,) def create(self, validated_data): GCMSs = validated_data.get('GCMSs') exploEviGCMSId = validated_data.get('exploEviGCMS') # type = validated_data.get('type') GCMS2s = [] result = [] filePath = "" TICId = 0 nameList = [] # 差错检验 if len(GCMSs) == 0: raise APIException("没有上传GC_MS文件,请上传") if exploEviGCMS.objects.filter(id=int(exploEviGCMSId)).count() != 1: raise APIException("填入的炸药GC_MS序号不存在,请重新输入") for index, url in enumerate(GCMSs): if os.path.splitext(url.name)[-1] != '.txt': raise APIException("有GC_MS文件不是txt格式,请检查。") name = url.name type = os.path.splitext(name)[0] nameList.append(type) if "TIC" not in nameList: raise APIException("上传的GC_MS文件中没有TIC.txt文档,请重新上传") exploEviGCMS1 = exploEviGCMS.objects.get(id=int(exploEviGCMSId)) for index, url in enumerate(GCMSs): # 会自动填入exploSampleId # 从url中知道type,如果是TIC的type,那么就创建一个以此id和样本id联合的文件夹用来存放这一批的文档, # 先存下来,再移动 GCMS = exploEviGCMSTestFile.objects.create( txtURL=url, exploEviGCMS=exploEviGCMS1, exploEviId=exploEviGCMS1.exploEvi_id) name = url.name type = os.path.splitext(name)[0] GCMS.type = type GCMS.save() if type == "TIC": filePath = os.path.join( MEDIA_ROOT, "file/exploEviGCMSTestFile/%d_%d/" % (GCMS.exploEviId, GCMS.id)) os.makedirs(filePath) TICId = GCMS.id GCMS2s.append(GCMS) for GCMS2 in GCMS2s: prePath = os.path.join(MEDIA_ROOT, str(GCMS2.txtURL)) name = os.path.basename(prePath) newPath = os.path.join(filePath, name) if os.path.exists(prePath) == False: raise APIException("上传的GC_MS文件夹路径被更改,找不到文件夹,无法进行预处理") #移动文件(目录) shutil.move(prePath, newPath) GCMS2.txtURL = newPath GCMS2.save() # 预处理方法,给filePath即为所在的文件夹 # blog = exploSampleGCMSFileSerializer(GCMS2, context=self.context) # GCMS3s.append(blog.data['handledData']) # 处理完一批我就删掉? # 对上传的文档预处理取平均,再将取完平均的回填到exploSampleGCMSAverFile GCMSFile = exploEviGCMSFile.objects.create( exploEviGCMS=exploEviGCMS1, exploEviId=exploEviGCMS1.exploEvi_id) result = preProcess('GCMS', exploEviGCMS1.id, GCMSFile.id, filePath) if result[0] == '0': GCMSFile.txtHandledURL = result[1] GCMSFile.save() # result = preProcess('GCMS', exploEviGCMS.id, TICId, filePath) # if result[0] == '0': # exploEviGCMSFile.objects.create(exploEviGCMS = exploEviGCMS,exploEviId =exploEviGCMS.exploEvi_id, txtHandledURL = result[1]) else: raise APIException("预处理过程出错") return {}
class FileUploadSerializer(serializers.Serializer): """Сериализатор для добавления связей""" file = serializers.FileField(use_url=False)
class ArtifactSerializer(base.ModelSerializer): pulp_href = base.IdentityField(view_name='artifacts-detail', ) file = serializers.FileField( help_text=_("The stored file."), allow_empty_file=True, ) size = serializers.IntegerField( help_text=_("The size of the file in bytes."), required=False, ) md5 = serializers.CharField( help_text=_("The MD5 checksum of the file if available."), required=False, allow_null=True, ) sha1 = serializers.CharField( help_text=_("The SHA-1 checksum of the file if available."), required=False, allow_null=True, ) sha224 = serializers.CharField( help_text=_("The SHA-224 checksum of the file if available."), required=False, allow_null=True, ) sha256 = serializers.CharField( help_text=_("The SHA-256 checksum of the file if available."), required=False, allow_null=True, ) sha384 = serializers.CharField( help_text=_("The SHA-384 checksum of the file if available."), required=False, allow_null=True, ) sha512 = serializers.CharField( help_text=_("The SHA-512 checksum of the file if available."), required=False, allow_null=True, ) def validate(self, data): """ Validate file by size and by all checksums provided. Args: data (:class:`django.http.QueryDict`): QueryDict mapping Artifact model fields to their values Raises: :class:`rest_framework.exceptions.ValidationError`: When the expected file size or any of the checksums don't match their actual values. """ super().validate(data) if 'size' in data: if data['file'].size != int(data['size']): raise serializers.ValidationError( _("The size did not match actual size of file.")) else: data['size'] = data['file'].size for algorithm in hashlib.algorithms_guaranteed: if algorithm in models.Artifact.DIGEST_FIELDS: digest = data['file'].hashers[algorithm].hexdigest() if algorithm in data and digest != data[algorithm]: raise serializers.ValidationError( _("The %s checksum did not match.") % algorithm) else: data[algorithm] = digest if algorithm in UNIQUE_ALGORITHMS: validator = UniqueValidator( models.Artifact.objects.all(), message=_("{0} checksum must be " "unique.").format(algorithm)) validator.field_name = algorithm validator.instance = None validator(digest) return data class Meta: model = models.Artifact fields = base.ModelSerializer.Meta.fields + ( 'file', 'size', 'md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
def make_serializer_class( meta_model, api_namespace=DEFAULT_API_NAMESPACE, limit_fields=None, nested=True, safe=False, ): enum_fields = list(meta_model.get_fields()) dict_fields = OrderedDict(enum_fields) _all_fields = ( list(dict_fields.keys()) + list(get_common_fields().keys()) + ['url', 'verbose_name'] ) custom_fields_names, custom_fields_attrs = make_custom_serializer_fields( meta_model, api_namespace=api_namespace ) _all_fields += custom_fields_names if meta_model.get_model_name() not in ('User',): _all_fields += get_user_tracked_fields().keys() if meta_model.get_model_name() not in ('User', DIVIDER_MODEL): _all_fields += ['scopes'] api_display_fields = meta_model.get_property('m_api_list_display') or [] if api_display_fields == []: if limit_fields is None: _fields = _all_fields else: _fields = [f for f in _all_fields if f in limit_fields] else: _fields = api_display_fields if meta_model.get_model_name() == 'User' and api_display_fields == []: _fields += [ 'last_name', 'first_name', "{}s".format(DIVIDER_MODEL.lower()), "admin", "is_staff", "level", "unsubscribe_notification_url", "unsubscribe_all", "unsubscribe_to", "external_auth", ] if safe: _fields += ['email'] # TODO: rajouter les <name>_uid dans _fields fk_read_only_fields = [] for name, field in enum_fields: if field.type.startswith("rel_"): _fields += ['{}_uid'.format(name)] fk_read_only_fields += [name] class Meta: model = concrete.models[meta_model.get_model_name().lower()] fields = _fields read_only_fields = ( ['created_by', 'admin', 'is_staff'] + fk_read_only_fields + [f for f in _all_fields if f.startswith('resource_')] ) extra_kwargs = { name: {'required': is_field_required(field)} for name, field in enum_fields } # TODO: DEACTIVATED by LCO on 06/11/18 # vars_model = vars(model) # for key, value in vars_model.items(): # # TODO: Exclude model User # if isinstance(value, ReverseManyToOneDescriptor): # if not (key.startswith('divider') or (key.startswith('can'))): # fields.append(key) # read_only_fields.append(key) attrs = {'Meta': Meta} # TODO : if field is relational, expose pk and url serialized for name, field in enum_fields: if field.f_type == 'FileField': attrs.update( { name: serializers.FileField( required=False, allow_null=True, validators=[validate_file], ) } ) if field.f_type == 'PointField': attrs.update( { name: PointField( required=not field.f_args.get("blank", False), allow_null=True, ) } ) if field.f_type == 'JSONField': attrs.update( {name: serializers.JSONField(binary=False, required=False)} ) if field.type.startswith("rel_") and nested is True: force_nested = getattr(field, 'force_nested', False) attrs.update( { name: make_related_serializer_class( target_model_name=field.f_args['to'], many=(field.type == 'rel_iterable'), nested=force_nested, api_namespace=api_namespace, ) } ) attrs.update(custom_fields_attrs) class _ModelSerializer(serializers.ModelSerializer): url = serializers.SerializerMethodField() verbose_name = serializers.SerializerMethodField() scopes = serializers.SerializerMethodField() def get_scopes(self, obj): divider = getattr(obj, DIVIDER_MODEL.lower(), None) if divider: return {"entity_uid": divider.uid} return None def get_url(self, obj): uri = reverse( "{}:{}-detail".format( api_namespace, meta_model.get_dashed_case_class_name() ), args=(obj.pk,), ) if hasattr(self, '_context'): if 'request' in self._context: request = self._context['request'] return request.build_absolute_uri(uri) return build_absolute_uri(uri) # skip-test-coverage def get_verbose_name(self, obj): try: return str(obj) except Exception: return '' for name, field in enum_fields: attrs.update({f'validate_{name}': get_field_validator(field=field)}) if field.type.startswith("rel_i"): x = field.f_args["to"].split('.') field_model = apps.get_model(app_label=x[0], model_name=x[1]) required = not field.f_args.get("blank", False) attrs.update( { '{}_uid'.format(name): serializers.PrimaryKeyRelatedField( source=name, many=True, allow_null=True, required=required, queryset=field_model.objects.all(), ) } ) if field.type.startswith("rel_s"): # Ex: concrete.Category, split to get # Django model with apps.get_model() x = field.f_args["to"].split('.') field_model = apps.get_model(app_label=x[0], model_name=x[1]) required = not field.f_args.get("blank", False) null = field.f_args.get("null", False) attrs.update( { '{}_uid'.format(name): serializers.PrimaryKeyRelatedField( many=False, source=name, allow_null=null, required=required, queryset=field_model.objects.all(), ) } ) if meta_model.get_model_name() == 'User': attrs.update({'level': serializers.CharField()}) def validate_level(self, value): value = value.lower() if value not in LIST_USER_LEVEL: raise serializers.ValidationError("Wrong value") else: user_level = self.context.get('request').user.level forbidden_for_admin = user_level == "admin" and value in [ "admin", "superuser", ] forbidden_for_manager = user_level == "manager" and value in [ "admin", "superuser", "manager", "blocked", ] forbidden_for_simple = user_level == "simpleuser" if ( forbidden_for_manager or forbidden_for_admin or forbidden_for_simple ): raise serializers.ValidationError( "You don't have permission to set this level" ) return value _ModelSerializer.validate_level = validate_level attrs.update( { 'unsubscribe_notification_url': serializers.SerializerMethodField( 'get_unsubscribe_url' ) } ) def get_unsubscribe_url(self, obj): return '{scheme}://{domain}:{port}{uri}'.format( scheme=settings.SCHEME, domain=settings.HOSTNAME, port=settings.PORT, uri=reverse( 'concrete:unsubscribe_notifications', kwargs={'token': obj.subscription_notification_token}, ), ) _ModelSerializer.get_unsubscribe_url = get_unsubscribe_url api_model_serializer = type( str('{}ModelSerializer'.format(meta_model.get_model_name())), (_ModelSerializer,), attrs, ) return api_model_serializer
class CsvUploadSerializer(serializers.ModelSerializer): document = serializers.FileField(use_url = False) class Meta: model = CsvUpload fields = ('pk', 'document', 'upload_date')
class ComponentSerializer(RemovableSerializer): web_url = AbsoluteURLField(source="get_absolute_url", read_only=True) project = ProjectSerializer(read_only=True) repository_url = MultiFieldHyperlinkedIdentityField( view_name="api:component-repository", lookup_field=("project__slug", "slug")) translations_url = MultiFieldHyperlinkedIdentityField( view_name="api:component-translations", lookup_field=("project__slug", "slug")) statistics_url = MultiFieldHyperlinkedIdentityField( view_name="api:component-statistics", lookup_field=("project__slug", "slug")) lock_url = MultiFieldHyperlinkedIdentityField( view_name="api:component-lock", lookup_field=("project__slug", "slug")) links_url = MultiFieldHyperlinkedIdentityField( view_name="api:component-links", lookup_field=("project__slug", "slug")) changes_list_url = MultiFieldHyperlinkedIdentityField( view_name="api:component-changes", lookup_field=("project__slug", "slug")) license_url = serializers.CharField(read_only=True) source_language = LanguageSerializer(required=False) repo = RepoField(max_length=REPO_LENGTH) push = RepoField(required=False, allow_blank=True, max_length=REPO_LENGTH) serializer_url_field = MultiFieldHyperlinkedIdentityField zipfile = serializers.FileField(required=False) docfile = serializers.FileField(required=False) enforced_checks = serializers.JSONField(required=False) task_url = RelatedTaskField(lookup_field="background_task_id") addons = serializers.HyperlinkedIdentityField( view_name="api:addon-detail", source="addon_set", many=True, read_only=True, ) class Meta: model = Component fields = ( "name", "slug", "id", "source_language", "project", "vcs", "repo", "git_export", "branch", "push_branch", "filemask", "template", "edit_template", "intermediate", "new_base", "file_format", "license", "license_url", "agreement", "web_url", "url", "repository_url", "translations_url", "statistics_url", "lock_url", "links_url", "changes_list_url", "task_url", "new_lang", "language_code_style", "push", "check_flags", "priority", "enforced_checks", "restricted", "repoweb", "report_source_bugs", "merge_style", "commit_message", "add_message", "delete_message", "merge_message", "addon_message", "allow_translation_propagation", "manage_units", "enable_suggestions", "suggestion_voting", "suggestion_autoaccept", "push_on_commit", "commit_pending_age", "auto_lock_error", "language_regex", "variant_regex", "zipfile", "docfile", "addons", "is_glossary", "glossary_color", ) extra_kwargs = { "url": { "view_name": "api:component-detail", "lookup_field": ("project__slug", "slug"), } } def to_representation(self, instance): """Remove VCS properties if user has no permission for that.""" result = super().to_representation(instance) user = self.context["request"].user if not user.has_perm("vcs.view", instance): result["vcs"] = None result["repo"] = None result["branch"] = None result["filemask"] = None result["push"] = None return result def fixup_request_payload(self, data): if "source_language" in data: language = data["source_language"] data["source_language"] = Language.objects.get( code=language if isinstance(language, str ) else language["code"]) if "project" in self._context: data["project"] = self._context["project"] if "manage_units" not in data: data["manage_units"] = bool(data.get("template")) def to_internal_value(self, data): # Preprocess to inject params based on content if "docfile" in data: fake_data = data.copy() self.fixup_request_payload(fake_data) fake = create_component_from_doc(fake_data) data["project"] = self._context["project"] data["template"] = fake.template data["new_base"] = fake.template data["filemask"] = fake.filemask data["repo"] = "local:" data["vcs"] = "local" data["branch"] = "main" data.pop("docfile") if "zipfile" in data: fake_data = data.copy() self.fixup_request_payload(fake_data) try: create_component_from_zip(fake_data) except BadZipfile: raise serializers.ValidationError( "Failed to parse uploaded ZIP file.") data["repo"] = "local:" data["vcs"] = "local" data["branch"] = "main" data.pop("zipfile") # DRF processing result = super().to_internal_value(data) # Postprocess to inject values self.fixup_request_payload(result) return result def validate(self, attrs): # Call model validation here, DRF does not do that instance = Component(**attrs) instance.clean() return attrs
class PlaybookSerializer(core_serializers.AugmentedSerializerMixin, serializers.HyperlinkedModelSerializer): archive = serializers.FileField(write_only=True) parameters = PlaybookParameterSerializer(many=True) class Meta(object): model = playbook_jobs_models.Playbook fields = ('url', 'uuid', 'name', 'description', 'archive', 'entrypoint', 'parameters', 'image') protected_fields = ('entrypoint', 'parameters', 'archive') extra_kwargs = { 'url': { 'lookup_field': 'uuid' }, } def validate_archive(self, value): if not is_zipfile(value): raise serializers.ValidationError(_('ZIP file must be uploaded.')) elif not value.name.endswith('.zip'): raise serializers.ValidationError( _("File must have '.zip' extension.")) zip_file = ZipFile(value) invalid_file = zip_file.testzip() if invalid_file is not None: raise serializers.ValidationError( _('File {filename} in archive {archive_name} has an invalid type.' .format(filename=invalid_file, archive_name=zip_file.filename))) return value def validate(self, attrs): if self.instance: return attrs zip_file = ZipFile(attrs['archive']) entrypoint = attrs['entrypoint'] if entrypoint not in zip_file.namelist(): raise serializers.ValidationError( _('Failed to find entrypoint {entrypoint} in archive {archive_name}.' .format(entrypoint=entrypoint, archive_name=zip_file.filename))) return attrs @transaction.atomic def create(self, validated_data): parameters_data = validated_data.pop('parameters') archive = validated_data.pop('archive') validated_data[ 'workspace'] = playbook_jobs_models.Playbook.generate_workspace_path( ) zip_file = ZipFile(archive) zip_file.extractall(validated_data['workspace']) zip_file.close() playbook = playbook_jobs_models.Playbook.objects.create( **validated_data) for parameter_data in parameters_data: playbook_jobs_models.PlaybookParameter.objects.create( playbook=playbook, **parameter_data) return playbook
class FileUploadSerializer(serializers.Serializer): file = serializers.FileField() class Meta: fields = ('file',)
class JobSerializer(common_serializers.BaseApplicationSerializer, structure_serializers.PermissionFieldFilteringMixin): service_project_link = serializers.HyperlinkedRelatedField( lookup_field='pk', view_name='openstacktenant-spl-detail', queryset=openstack_models.OpenStackTenantServiceProjectLink.objects. all(), ) service = serializers.HyperlinkedRelatedField( source='service_project_link.service', lookup_field='uuid', view_name='openstacktenant-detail', read_only=True, ) service_name = serializers.ReadOnlyField( source='service_project_link.service.settings.name') service_uuid = serializers.ReadOnlyField( source='service_project_link.service.uuid') ssh_public_key = serializers.HyperlinkedRelatedField( lookup_field='uuid', view_name='sshpublickey-detail', queryset=core_models.SshPublicKey.objects.all(), required=True, ) ssh_public_key_name = serializers.ReadOnlyField( source='ssh_public_key.name') ssh_public_key_uuid = serializers.ReadOnlyField( source='ssh_public_key.uuid') project = serializers.HyperlinkedRelatedField( source='service_project_link.project', lookup_field='uuid', view_name='project-detail', read_only=True, ) project_name = serializers.ReadOnlyField( source='service_project_link.project.name') project_uuid = serializers.ReadOnlyField( source='service_project_link.project.uuid') playbook = serializers.HyperlinkedRelatedField( lookup_field='uuid', view_name=core_utils.get_detail_view_name( playbook_jobs_models.Playbook), queryset=playbook_jobs_models.Playbook.objects.all(), ) playbook_name = serializers.ReadOnlyField(source='playbook.name') playbook_uuid = serializers.ReadOnlyField(source='playbook.uuid') playbook_image = serializers.FileField(source='playbook.image', read_only=True) playbook_description = serializers.ReadOnlyField( source='playbook.description') arguments = serializers.JSONField(default=dict) state = serializers.SerializerMethodField() tag = serializers.SerializerMethodField() type = serializers.SerializerMethodField() class Meta(object): model = playbook_jobs_models.Job fields = ('url', 'uuid', 'name', 'description', 'service_project_link', 'service', 'service_name', 'service_uuid', 'ssh_public_key', 'ssh_public_key_name', 'ssh_public_key_uuid', 'project', 'project_name', 'project_uuid', 'playbook', 'playbook_name', 'playbook_uuid', 'playbook_image', 'playbook_description', 'arguments', 'state', 'output', 'created', 'modified', 'tag', 'type') read_only_fields = ('output', 'created', 'modified', 'type') protected_fields = ('service_project_link', 'ssh_public_key', 'playbook', 'arguments') extra_kwargs = { 'url': { 'lookup_field': 'uuid' }, } def get_type(self, obj): return 'playbook_job' def get_filtered_field_names(self): return 'project', 'service_project_link', 'ssh_public_key' def get_state(self, obj): return obj.get_state_display() def get_tag(self, obj): return obj.get_tag() def check_project(self, attrs): if self.instance: project = self.instance.service_project_link.project else: project = attrs['service_project_link'].project if not structure._has_admin_access(self.context['request'].user, project): raise exceptions.PermissionDenied() def check_arguments(self, attrs): playbook = self.instance.playbook if self.instance else attrs[ 'playbook'] arguments = attrs['arguments'] parameter_names = playbook.parameters.all().values_list('name', flat=True) for argument in arguments.keys(): if argument not in parameter_names and argument != 'project_uuid': raise serializers.ValidationError( _('Argument %s is not listed in playbook parameters.' % argument)) if playbook.parameters.exclude(name__in=arguments.keys()).filter( required=True, default__exact='').exists(): raise serializers.ValidationError( _('Not all required playbook parameters were specified.')) unfilled_parameters = playbook.parameters.exclude( name__in=arguments.keys()) for parameter in unfilled_parameters: if parameter.default: arguments[parameter.name] = parameter.default def check_subnet(self, attrs): if not self.instance: settings = attrs['service_project_link'].service.settings if not openstack_models.SubNet.objects.filter( settings=settings).exists(): raise serializers.ValidationError( _('Selected OpenStack provider does not have any subnet yet.' )) else: attrs['subnet'] = openstack_models.SubNet.objects.filter( settings=settings).first() def validate(self, attrs): if not self.instance: attrs['user'] = self.context['request'].user self.check_project(attrs) self.check_arguments(attrs) self.check_subnet(attrs) return attrs
class FileSerializer(serializers.Serializer): """ Serializer for the uploaded file """ uploaded_file = serializers.FileField(use_url=False)
class ImagemSerializer(serializers.ModelSerializer): datafile = serializers.FileField(required=False) class Meta: model = Imagem fields = ('id', 'datafile')
class ImagesProductsSerializer(serializers.ModelSerializer): image = serializers.FileField('image.url') class Meta: model = ImagesProduct fields = '__all__'
class AnnotationFileSerializer(serializers.Serializer): annotation_file = serializers.FileField()
class ItemSerializer(serializers.Serializer): attachment = serializers.FileField()
class BlobSerializer(serializers.ModelSerializer): data = serializers.FileField() class Meta: model = Blob fields = ['floor_id', 'data']
class XSerializer(serializers.Serializer): file = serializers.FileField()
class PictureSerializer(BaseModelWithCreatedByAndSoftDeleteSerializer, EntityMetadataSerializerMixin): """ REST API Serializer for Picture """ projects = ProjectPrimaryKeyRelatedField(many=True, required=False) download_shapes = serializers.SerializerMethodField(read_only=True) download_background_image = serializers.SerializerMethodField( read_only=True) download_rendered_image = serializers.SerializerMethodField(read_only=True) metadata = EntityMetadataSerializer( read_only=False, many=True, required=False, ) def get_download_shapes(self, picture): return self.build_download_url(picture, 'picture-shapes-json') def get_download_background_image(self, picture): return self.build_download_url_with_token(picture, 'picture-background-image') def get_download_rendered_image(self, picture): if not picture.rendered_image: return self.get_download_background_image(picture) return self.build_download_url_with_token(picture, 'picture-rendered-image') @staticmethod def build_download_url_with_token(picture, reverse_url_name): request = get_current_request() if picture.uploaded_picture_entry is None: raise IntegrityError("uploaded_picture_entry is not referenced") path = reverse(reverse_url_name, kwargs={'pk': picture.uploaded_picture_entry.pk}) return build_expiring_jwt_url(request, path) @staticmethod def build_download_url(picture, reverse_url_name): request = get_current_request() path = reverse(reverse_url_name, kwargs={'pk': picture.uploaded_picture_entry.pk}) return request.build_absolute_uri(path) # all files should be write only - we have the download links as alternative # write only for the shapes shapes_image = serializers.FileField(write_only=True, required=False) # write only for the background image background_image = serializers.FileField(write_only=True, required=False) # write only for the rendered image rendered_image = serializers.FileField(write_only=True, required=False) class Meta: model = Picture fields = ('title', 'shapes_image', 'background_image', 'rendered_image', 'projects', 'width', 'height', 'created_by', 'created_at', 'last_modified_by', 'last_modified_at', 'version_number', 'download_shapes', 'download_background_image', 'download_rendered_image', 'url', 'metadata', 'is_favourite') @transaction.atomic def create(self, validated_data): metadata_list = self.pop_metadata(validated_data) instance = super().create(validated_data) self.create_metadata(metadata_list, instance) return instance @transaction.atomic def update(self, instance, validated_data): metadata_list = self.pop_metadata(validated_data) self.update_metadata(metadata_list, instance) return super().update(instance, validated_data)
class BadgeConnectAssertionSerializer(BadgeConnectBaseEntitySerializer): id = serializers.URLField(source='jsonld_id', read_only=True) badge = serializers.URLField(source='badgeclass_jsonld_id', read_only=True) image = serializers.FileField(read_only=True) recipient = BadgeRecipientSerializerV2(source='*') issuedOn = serializers.DateTimeField(source='issued_on', read_only=True) narrative = MarkdownCharField(required=False) evidence = EvidenceItemSerializerV2(many=True, required=False) revoked = HumanReadableBooleanField(read_only=True) revocationReason = serializers.CharField(source='revocation_reason', read_only=True) expires = serializers.DateTimeField(source='expires_at', required=False) type = serializers.CharField(read_only=True, default='Assertion') class Meta: SCHEMA_TYPE = 'Assertion' model = BadgeInstance apispec_definition = ('BadgeConnectAssertion', { 'properties': OrderedDict([ ('id', { 'type': "string", 'format': "url", 'readOnly': True, 'description': "URL of the BadgeInstance", }), ('badge', { 'type': "string", 'format': "url", 'readOnly': True, 'description': "URL of the BadgeClass", }), ('image', { 'type': "string", 'format': "string", 'readOnly': True, 'description': "Badge Image", }), ('recipient', { 'type': 'object', 'properties': BadgeRecipientSerializerV2.Meta.apispec_definition[1] ['properties'], 'readOnly': True, 'description': "Recipient that was issued the Assertion" }), ('issuedOn', { 'type': 'string', 'format': 'ISO8601 timestamp', 'readOnly': True, 'description': "Timestamp when the Assertion was issued", }), ('narrative', { 'type': 'string', 'format': 'markdown', 'description': "Markdown narrative of the achievement", }), ('evidence', { 'type': "string", 'format': "string", 'description': "Unique identifier for this Assertion", }), ('revoked', { 'type': 'boolean', 'readOnly': True, 'description': "True if this Assertion has been revoked", }), ('revocationReason', { 'type': 'string', 'format': "string", 'readOnly': True, 'description': "Short description of why the Assertion was revoked", }), ('expires', { 'type': 'string', 'format': 'ISO8601 timestamp', 'description': "Timestamp when the Assertion expires", }), ('@context', { 'type': 'string', 'format': 'url', 'default': CONTEXT_URI, 'example': CONTEXT_URI, }), ('type', { 'type': 'string', 'default': SCHEMA_TYPE, 'example': SCHEMA_TYPE }) ]) })
class ProductSerializer(serializers.ModelSerializer): # read_only decide wheather or not we can serialize using serializer is_on_sale = serializers.BooleanField(read_only=True) current_price = serializers.FloatField(read_only=True) description = serializers.CharField( min_length=2, max_length=200) # this will ensure validation cart_items = serializers.SerializerMethodField() price = serializers.DecimalField( min_value=1.00, max_value=100000, max_digits=None, decimal_places=2, ) sale_start = serializers.DateTimeField( required=False, input_formats=['%I:%M %p %d %B %Y'], format=None, allow_null=True, help_text='Accepted format is "12:03 PM 16 April 2018"', style={ 'input_type': 'text', 'placeholder': '12:03 PM 16 July 2020' }, ) sale_end = serializers.DateTimeField( required=False, input_formats=['%I:%M %p %d %B %Y'], format=None, allow_null=True, help_text='Accepted format is "12:03 PM 16 April 2018"', style={ 'input_type': 'text', 'placeholder': '12:03 PM 16 July 2020' }, ) photo = serializers.ImageField(default=None) warranty = serializers.FileField(write_only=True, default=None) class Meta: model = Product fields = ( 'id', 'name', 'description', 'price', 'sale_start', 'sale_end', 'current_price', 'is_on_sale', 'cart_items', 'photo', 'warranty', ) def get_cart_items(self, instance): items = ShoppingCartItem.objects.filter(product=instance) return CartItemSerializer(items, many=True).data def update(self, instance, validated_data): if validated_data.get('warranty'): instance.description += '\n\nWarranty\n\n' instance.description += b'; '.join( validated_data['warranty'].readlines()).decode() return super().update(instance, validated_data) def create(self, validated_data): validated_data.pop('warranty') return Product.objects.create(**validated_data)
class AttachmentSerializer(serializers.ModelSerializer): file = serializers.FileField(required=False, write_only=True) filename = serializers.CharField(max_length=255, required=False) url = serializers.SerializerMethodField() download_url = serializers.SerializerMethodField() view_url = serializers.SerializerMethodField() class Meta: model = Attachment fields = ( 'id', 'url', 'download_url', 'view_url', 'file', 'filename', 'mime_type', 'size', 'created_at', 'updated_at', ) read_only_fields = ('created_at', 'updated_at', 'mime_type', 'size') def get_url(self, instance): if not instance.pk: return None return reverse('document-attachments-detail', request=self.context['request'], kwargs={ 'document_id': instance.document.pk, 'pk': instance.pk, }) def get_download_url(self, instance): if not instance.pk: return None return reverse('document-attachments-download', request=self.context['request'], kwargs={ 'document_id': instance.document.pk, 'pk': instance.pk, }) def get_view_url(self, instance): if not instance.pk: return None return reverse('document-attachments-view', request=self.context['request'], kwargs={ 'document_id': instance.document.pk, 'pk': instance.pk, }) def create(self, validated_data): file = validated_data.get('file', None) if not file: raise ValidationError({'file': "No file was submitted."}) args = {} args.update(validated_data) args['size'] = file.size args['mime_type'] = file.content_type args['filename'] = args.get('filename', os.path.basename(file.name)) args['document'] = args.get('document', self.context['document']) return super(AttachmentSerializer, self).create(args) def update(self, instance, validated_data): if 'file' in validated_data: raise ValidationError( "Value of 'file' cannot be updated. Delete and re-create this attachment." ) return super(AttachmentSerializer, self).update(instance, validated_data) def validate_filename(self, fname): return fname.replace('/', '')
class HeadshotUploadSerializer(serializers.Serializer): file = serializers.FileField()