class PostSerializer(serializers.ModelSerializer): tags = serializers.SlugRelatedField(many=True, slug_field='label', queryset=Tag.objects.all()) class Meta: model = Post exclude = []
class AddressSerializer(serializers.ModelSerializer): user = serializers.SlugRelatedField(queryset=User.objects.all(), slug_field='username') class Meta: model = Address
class EventFullSerializer(serializers.ModelSerializer): """Serializer for Event with more information. Returns a nested list of followers of each status and detailed information on venues. """ from bodies.serializer_min import BodySerializerMin from locations.serializers import LocationSerializerMin from locations.models import Location from bodies.models import Body interested_count = serializers.IntegerField(read_only=True) going_count = serializers.IntegerField(read_only=True) interested = serializers.SerializerMethodField() get_interested = lambda self, obj: get_followers(obj, 1) going = serializers.SerializerMethodField() get_going = lambda self, obj: get_followers(obj, 2) user_ues = serializers.SerializerMethodField() get_user_ues = get_user_ues venues = LocationSerializerMin(many=True, read_only=True) venue_names = serializers.SlugRelatedField(many=True, read_only=True, slug_field='name', source='venues') venue_ids = serializers.PrimaryKeyRelatedField( many=True, read_only=False, source='venues', queryset=Location.objects.all(), required=False) bodies = BodySerializerMin(many=True, read_only=True) bodies_id = serializers.PrimaryKeyRelatedField(many=True, read_only=False, queryset=Body.objects.all(), source='bodies') user_tags = serializers.PrimaryKeyRelatedField( many=True, read_only=False, queryset=UserTag.objects.all(), default=[]) class Meta: model = Event fields = ('id', 'str_id', 'name', 'description', 'image_url', 'start_time', 'end_time', 'all_day', 'venues', 'venue_names', 'bodies', 'bodies_id', 'interested_count', 'going_count', 'interested', 'going', 'venue_ids', 'website_url', 'user_ues', 'notify', 'user_tags') @staticmethod def setup_eager_loading(queryset, request): """Calls the method in EventSerializer adding ues__user""" return EventSerializer.setup_eager_loading( queryset, request, extra_prefetch=['ues', 'ues__user']) def to_representation(self, instance): result = super().to_representation(instance) # Remove unnecessary fields result.pop('venue_ids') return result def create(self, validated_data): validated_data['created_by'] = self.context['request'].user.profile return super().create(validated_data)
class ProgramSerializer(MinimalProgramSerializer): authoring_organizations = OrganizationSerializer(many=True) video = VideoSerializer() expected_learning_items = serializers.SlugRelatedField(many=True, read_only=True, slug_field='value') faq = FAQSerializer(many=True) credit_backing_organizations = OrganizationSerializer(many=True) corporate_endorsements = CorporateEndorsementSerializer(many=True) job_outlook_items = serializers.SlugRelatedField(many=True, read_only=True, slug_field='value') individual_endorsements = EndorsementSerializer(many=True) languages = serializers.SlugRelatedField( many=True, read_only=True, slug_field='code', help_text=_( 'Languages that course runs in this program are offered in.'), ) transcript_languages = serializers.SlugRelatedField( many=True, read_only=True, slug_field='code', help_text= _('Languages that course runs in this program have available transcripts in.' ), ) subjects = SubjectSerializer(many=True) staff = PersonSerializer(many=True) @classmethod def prefetch_queryset(cls): """ Prefetch the related objects that will be serialized with a `Program`. We use Pefetch objects so that we can prefetch and select all the way down the chain of related fields from programs to course runs (i.e., we want control over the querysets that we're prefetching). """ return Program.objects.all( ).select_related('type', 'video', 'partner').prefetch_related( 'excluded_course_runs', 'expected_learning_items', 'faq', 'job_outlook_items', # `type` is serialized by a third-party serializer. Providing this field name allows us to # prefetch `applicable_seat_types`, a m2m on `ProgramType`, through `type`, a foreign key to # `ProgramType` on `Program`. 'type__applicable_seat_types', # We need the full Course prefetch here to get CourseRun information that methods on the Program # model iterate across (e.g. language). These fields aren't prefetched by the minimal Course serializer. Prefetch('courses', queryset=CourseSerializer.prefetch_queryset()), Prefetch('authoring_organizations', queryset=OrganizationSerializer.prefetch_queryset()), Prefetch('credit_backing_organizations', queryset=OrganizationSerializer.prefetch_queryset()), Prefetch( 'corporate_endorsements', queryset=CorporateEndorsementSerializer.prefetch_queryset()), Prefetch('individual_endorsements', queryset=EndorsementSerializer.prefetch_queryset()), ) class Meta(MinimalProgramSerializer.Meta): model = Program fields = MinimalProgramSerializer.Meta.fields + ( 'overview', 'weeks_to_complete', 'weeks_to_complete_min', 'weeks_to_complete_max', 'min_hours_effort_per_week', 'max_hours_effort_per_week', 'video', 'expected_learning_items', 'faq', 'credit_backing_organizations', 'corporate_endorsements', 'job_outlook_items', 'individual_endorsements', 'languages', 'transcript_languages', 'subjects', 'price_ranges', 'staff', 'credit_redemption_overview', )
class CreateFavoriteSerializer(serializers.Serializer): offer = serializers.SlugRelatedField(slug_field='uuid', queryset=Offer.objects.all())
class StaffCreateClientSerializer(serializers.ModelSerializer): groups = serializers.SlugRelatedField(slug_field='name', queryset=ClientGroup.objects.all(), many=True, required=False) configuration = serializers.SlugRelatedField( slug_field='name', queryset=Configuration.objects.all(), required=False) user = StaffUserSerializer(write_only=True, required=False) create_auto_order_service = serializers.BooleanField(required=False, default=False) auto_order_service_external_billing_id = serializers.CharField( max_length=38, allow_null=True, allow_blank=True, required=False) custom_fields = ClientCustomFieldSerializer(many=True, required=False) reseller_client = serializers.IntegerField(required=False, allow_null=True, default=0) class Meta: model = Client fields = ('id', 'first_name', 'last_name', 'company', 'address1', 'address2', 'city', 'country', 'state', 'zip_code', 'phone', 'fax', 'email', 'vat_id', 'groups', 'external_billing_id', 'currency', 'configuration', 'user', 'create_auto_order_service', 'auto_order_service_external_billing_id', 'custom_fields', 'reseller_client') read_only_fields = ('id', ) def validate(self, attrs): cf = ClientCustomFieldDefinition() try: cfs = cf.validate(new_fields=attrs, instance=self.instance) except Exception as e: raise serializers.ValidationError({'custom_fields': e}) attrs['custom_fields'] = [{ 'name': k, 'value': v } for k, v in iter(cfs.items())] vat_id = attrs.get('vat_id') country_code = attrs.get('country', None) if vat_id and country_code: valid_vat, message = validate_vat_id(vat_id=vat_id, country_code=country_code) if not valid_vat: raise serializers.ValidationError({'vat_id': message}) if not validate_client_limit(): raise serializers.ValidationError({ 'non_field_errors': _('License client limit reached. Please check your license'), }) return super(StaffCreateClientSerializer, self).validate(attrs) def create(self, validated_data): create_auto_order_service = validated_data.pop( 'create_auto_order_service', False) auto_order_service_external_billing_id = validated_data.pop( 'auto_order_service_external_billing_id', None) request_user = None request = self.context.get('request', None) if request and hasattr(request, 'user'): request_user = request.user user = validated_data.pop('user', None) groups = validated_data.pop('groups', list()) custom_fields = validated_data.pop('custom_fields', None) reseller_client = validated_data.pop('reseller_client', None) # type: Client if reseller_client: reseller_client_obj = Client.objects.get(id=reseller_client) validated_data['reseller_resources'] = client_reseller_resources( client=reseller_client_obj) with transaction.atomic(): # NOTE(tomo): We do all database actions first and create the # project which also calls the nova API, afterwards. db_client = super(StaffCreateClientSerializer, self).create(validated_data) if user: db_user = get_user_model().objects.create_user(**user) # TODO(tomo): is_client_admin should be configurable UserToClient.objects.create(user=db_user, client=db_client, is_client_admin=True) if isinstance(groups, list): for group in groups: db_client.groups.add(group) # Create the project if everything above is in order (calls the OpenStack API) if create_auto_order_service: client_created.send( sender=self.__class__, client=db_client, create_auto_order_service=True, auto_order_service_external_billing_id= auto_order_service_external_billing_id, request_user=request_user.id if request_user else None) for field in custom_fields: db_client.custom_fields.create(name=field['name'], value=field['value'], value_type='string') return db_client
class SolicitudSerializer(serializers.ModelSerializer): pruebas = PruebaSerializer(many=True) tipo_ejecucion = TipoEjecucionSerializer() herramienta = HerramientaSerializer() aplicacion = AplicacionSerializer() tipo_prueba = TipoPruebaSerializer() creado_por = serializers.SlugRelatedField( queryset=get_user_model().objects.all(), slug_field='username') class Meta: fields = ( 'id', 'nombre', 'aplicacion', 'herramienta', 'tipo_prueba', 'tipo_ejecucion', 'pruebas', 'descripcion', 'creado_por', ) model = Solicitud def save(self, **kwargs): super(SolicitudSerializer, self).save() sqs = boto3.client('sqs') queue_url = settings.SQS_QUEUE_URL response = sqs.send_message( QueueUrl=queue_url, DelaySeconds=10, MessageAttributes={ 'Id': { 'DataType': 'String', 'StringValue': str(self.data['id']) }, 'NombreAplicacion': { 'DataType': 'String', 'StringValue': Aplicacion.objects.filter( pk=self.data['aplicacion'])[0].nombre }, 'VersionAplicacion': { 'DataType': 'String', 'StringValue': Aplicacion.objects.filter( pk=self.data['aplicacion'])[0].version }, 'NombreHerramienta': { 'DataType': 'String', 'StringValue': Herramienta.objects.filter( pk=self.data['herramienta'])[0].nombre }, 'NombreEjecutor': { 'DataType': 'String', 'StringValue': Herramienta.objects.filter( pk=self.data['herramienta'])[0].ejecutor.ejecutor }, 'VersionEjecutor': { 'DataType': 'String', 'StringValue': Herramienta.objects.filter( pk=self.data['herramienta'])[0].ejecutor.version }, 'TipoPrueba': { 'DataType': 'String', 'StringValue': TipoPrueba.objects.filter( pk=self.data['tipo_prueba'])[0].tipo_prueba }, 'TipoEjecucion': { 'DataType': 'String', 'StringValue': TipoEjecucion.objects.filter( pk=self.data['tipo_ejecucion'])[0].tipo_ejecucion } }, MessageBody=json.dumps(self.data))
class ConfigSerializer(ModelSerializer): """Serialize a :class:`~api.models.Config` model.""" app = serializers.SlugRelatedField(slug_field='id', queryset=models.App.objects.all()) owner = serializers.ReadOnlyField(source='owner.username') values = JSONStringFieldSerializer(required=False) memory = JSONStringFieldSerializer(required=False) cpu = JSONIntFieldSerializer(required=False) tags = JSONStringFieldSerializer(required=False) created = serializers.DateTimeField(format=settings.DEIS_DATETIME_FORMAT, read_only=True) updated = serializers.DateTimeField(format=settings.DEIS_DATETIME_FORMAT, read_only=True) class Meta: """Metadata options for a :class:`ConfigSerializer`.""" model = models.Config def validate_values(self, value): for k, v in value.viewitems(): if not re.match(CONFIGKEY_MATCH, k): raise serializers.ValidationError( "Config keys must start with a letter or underscore and " "only contain [A-z0-9_]") return value def validate_memory(self, value): for k, v in value.viewitems(): if v is None: # use NoneType to unset a value continue if not re.match(PROCTYPE_MATCH, k): raise serializers.ValidationError( "Process types can only contain [a-z]") if not re.match(MEMLIMIT_MATCH, str(v)): raise serializers.ValidationError( "Limit format: <number><unit>, where unit = B, K, M or G") return value def validate_cpu(self, value): for k, v in value.viewitems(): if v is None: # use NoneType to unset a value continue if not re.match(PROCTYPE_MATCH, k): raise serializers.ValidationError( "Process types can only contain [a-z]") shares = re.match(CPUSHARE_MATCH, str(v)) if not shares: raise serializers.ValidationError( "CPU shares must be an integer") for v in shares.groupdict().viewvalues(): try: i = int(v) except ValueError: raise serializers.ValidationError( "CPU shares must be an integer") if i > 1024 or i < 0: raise serializers.ValidationError( "CPU shares must be between 0 and 1024") return value def validate_tags(self, value): for k, v in value.viewitems(): if v is None: # use NoneType to unset a value continue if not re.match(TAGKEY_MATCH, k): raise serializers.ValidationError( "Tag keys can only contain [a-z]") if not re.match(TAGVAL_MATCH, str(v)): raise serializers.ValidationError("Invalid tag value") return value
class CommentSerializer(serializers.ModelSerializer): author = serializers.SlugRelatedField(slug_field="username", read_only=True) class Meta: model = Comment fields = "__all__"
class DatasetSerializer(serializers.HyperlinkedModelSerializer): created_by = serializers.SlugRelatedField( read_only=False, slug_field='username', queryset=get_user_model().objects.all(), default=serializers.CurrentUserDefault(), ) dataset_type = serializers.SlugRelatedField( read_only=False, slug_field='name', queryset=DatasetType.objects.all(), ) data_format = serializers.SlugRelatedField( read_only=False, required=False, slug_field='name', queryset=DataFormat.objects.all(), ) session = serializers.HyperlinkedRelatedField( read_only=False, required=False, view_name="session-detail", queryset=Session.objects.all(), ) md5 = serializers.UUIDField( format='hex_verbose', allow_null=True, required=False, ) file_size = serializers.IntegerField(required=False) experiment_number = serializers.SerializerMethodField() file_records = DatasetFileRecordsSerializer(read_only=True, many=True) # If session is not provided, use subject, start_time, number subject = serializers.SlugRelatedField( write_only=True, required=False, slug_field='nickname', queryset=Subject.objects.all(), ) date = serializers.DateField(required=False) number = serializers.IntegerField(required=False) @staticmethod def setup_eager_loading(queryset): """ Perform necessary eager loading of data to avoid horrible performance.""" queryset = queryset.select_related('created_by', 'dataset_type', 'data_format', 'session', 'session__subject') queryset = queryset.prefetch_related('file_records', 'file_records__data_repository') return queryset def get_experiment_number(self, obj): return obj.session.number if obj and obj.session else None def create(self, validated_data): if validated_data.get('session', None): return super(DatasetSerializer, self).create(validated_data) # Find or create an appropriate session for the dataset. subject = validated_data.pop('subject', None) date = validated_data.pop('date', None) if not subject or not date: return super(DatasetSerializer, self).create(validated_data) # Only get or create the appropriate session if at least the subject and # date are provided. number = validated_data.pop('number', None) user = validated_data.pop('created_by', None) session = _get_session(subject=subject, date=date, number=number, user=user) # Create the dataset, attached to the subsession. validated_data['session'] = session return super(DatasetSerializer, self).create(validated_data) class Meta: model = Dataset fields = ('url', 'name', 'created_by', 'created_datetime', 'dataset_type', 'data_format', 'session', 'file_size', 'md5', 'experiment_number', 'file_records', 'subject', 'date', 'number') extra_kwargs = { 'subject': { 'write_only': True }, 'date': { 'write_only': True }, 'number': { 'write_only': True }, }
class FavoriteListSerializer(serializers.ModelSerializer): post_id = serializers.SlugRelatedField(read_only=True, slug_field='id') class Meta: model = Favorite fields = ['post_id']
class TaskSerializer(DynamicFieldsModelSerializer): default_error_messages = { 'status_change': 'Status change from "{old_status}" to "{new_status}" is not supported!' } # Not a job, but decision object! job = serializers.SlugRelatedField( slug_field='identifier', write_only=True, queryset=Decision.objects.select_related('scheduler')) def validate_job(self, instance): if instance.status == DECISION_STATUS[6][0]: raise serializers.ValidationError('The job is cancelling') if instance.status != DECISION_STATUS[2][0]: raise serializers.ValidationError('The job is not processing') if instance.scheduler.status == SCHEDULER_STATUS[2][0]: raise exceptions.ValidationError( 'The tasks scheduler is disconnected') return instance def validate_archive(self, archive): if not zipfile.is_zipfile(archive) or zipfile.ZipFile( archive).testzip(): raise exceptions.ValidationError( 'The task file "%s" is not a ZIP file' % archive) return archive def validate_description(self, desc): if not isinstance(desc, dict): raise exceptions.ValidationError('Not a dictionary') if 'priority' not in desc: raise exceptions.ValidationError('Task priority was not set') if desc['priority'] not in set(pr[0] for pr in PRIORITY): raise exceptions.ValidationError('Unsupported task priority value') return desc def validate_status(self, new_status): if not self.instance: raise exceptions.APIException( 'The status can be provided only for changing the task') old_status = self.instance.status # Finished (with error or not) task can't be finished again if old_status not in {TASK_STATUS[0][0], TASK_STATUS[1][0]}: self.fail('status_change', old_status=old_status, new_status=new_status) # Status is changed already if old_status == new_status: self.fail('status_change', old_status=old_status, new_status=new_status) # Processing task can't become pending again if old_status == TASK_STATUS[1][0] and new_status == TASK_STATUS[0][0]: self.fail('status_change', old_status=old_status, new_status=new_status) if new_status == TASK_STATUS[2][0]: if not Solution.objects.filter(task=self.instance).exists(): # logger.error("Task was finished without solutions") raise exceptions.ValidationError( "Task can't be finished without solutions") return new_status def validate(self, attrs): if 'status' in attrs: if attrs['status'] != TASK_STATUS[3][0]: attrs.pop('error', None) elif 'error' not in attrs: attrs['error'] = "The scheduler hasn't given error description" if 'description' in attrs and 'decision' in attrs: # Validate task priority job_priority = attrs['decision'].priority task_priority = attrs['description']['priority'] priority_list = list(pr[0] for pr in PRIORITY) if priority_list.index(job_priority) > priority_list.index( task_priority): raise exceptions.ValidationError( {'priority': 'Task priority is too big'}) return attrs def update_decision(self, decision, new_status, old_status=None): status_map = { TASK_STATUS[0][0]: 'tasks_pending', TASK_STATUS[1][0]: 'tasks_processing', TASK_STATUS[2][0]: 'tasks_finished', TASK_STATUS[3][0]: 'tasks_error', TASK_STATUS[4][0]: 'tasks_cancelled' } if old_status: # Decrement counter for old status decr_field = status_map[old_status] old_num = getattr(decision, decr_field) if old_num > 0: setattr(decision, decr_field, old_num - 1) else: logger.error( 'Something wrong with Decision: number of {} tasks is 0, ' 'but there is at least one such task in the system'.format( old_status)) else: # Task was created decision.tasks_total += 1 # Increment counter for new status incr_field = status_map[new_status] new_num = getattr(decision, incr_field) setattr(decision, incr_field, new_num + 1) decision.save() def create(self, validated_data): validated_data['filename'] = validated_data['archive'].name[:256] validated_data['decision'] = validated_data.pop('job') instance = super().create(validated_data) self.update_decision(instance.decision, instance.status) on_task_change(instance.id, instance.status, instance.decision.scheduler.type) return instance def update(self, instance, validated_data): assert isinstance(instance, Task) if 'status' not in validated_data: raise exceptions.ValidationError({'status': 'Required'}) if instance.decision.status != DECISION_STATUS[2][0]: raise serializers.ValidationError({'job': 'Is not processing'}) old_status = instance.status instance = super().update(instance, validated_data) self.update_decision(instance.decision, instance.status, old_status=old_status) on_task_change(instance.id, instance.status, instance.decision.scheduler.type) return instance def to_representation(self, instance): if isinstance(instance, Task) and 'request' in self.context and self.context[ 'request'].method != 'GET': return {'id': instance.id} return super().to_representation(instance) class Meta: model = Task exclude = ('decision', 'filename') extra_kwargs = {'archive': {'write_only': True}}
class BookingSerializer(serializers.ModelSerializer): flight = serializers.SlugRelatedField(slug_field='destination', read_only=True) class Meta: model = Booking fields = ['flight', 'date', 'id']
class SubEventCheckSerializer(serializers.Serializer): attendee = serializers.PrimaryKeyRelatedField(queryset=Attendee.objects) subevent = serializers.SlugRelatedField(queryset=SubEvent.objects, slug_field='id') force = serializers.BooleanField(default=False, required=False) check = serializers.BooleanField(required=True)
class AquiferSerializer(serializers.ModelSerializer): """Serialize a aquifer list""" demand_description = serializers.SlugRelatedField(source='demand', read_only=True, slug_field='description') material_description = serializers.SlugRelatedField( source='material', read_only=True, slug_field='description') productivity_description = serializers.SlugRelatedField( source='productivity', read_only=True, slug_field='description') subtype_description = serializers.StringRelatedField(source='subtype', read_only=True) vulnerability_description = serializers.SlugRelatedField( source='vulnerability', read_only=True, slug_field='description') quality_concern_description = serializers.SlugRelatedField( source='quality_concern', read_only=True, slug_field='description') known_water_use_description = serializers.SlugRelatedField( source='known_water_use', read_only=True, slug_field='description') resources = AquiferResourceSerializer(many=True, required=False) def create(self, validated_data): """ Allow creating resources inline of the aquifer API. ie) { resources: [{ url: 'http://...', name: 'A resource', section_id: 1 }, { ... }, ...] ... } """ resources_data = validated_data.pop('resources') aquifer = models.Aquifer.objects.create(**validated_data) for resource_item in resources_data: r = models.AquiferResource( url=resource_item['url'], name=resource_item['name'], aquifer=aquifer, section_id=resource_item['section']['code'].code) r.save() return aquifer def update(self, instance, validated_data): """ Update the resources associated with an aquifer, inline of the aquifer API. """ resources_data = validated_data.pop('resources', []) for k, v in validated_data.items(): setattr(instance, k, v) instance.save() # Any items removed from the inline collection are deleted. to_delete = models.AquiferResource.objects.filter( aquifer=instance).exclude( id__in=[r['id'] for r in resources_data if 'id' in r]) to_delete.delete() for resource_item in resources_data: if 'instance' in resource_item: resource = resource_item['instance'] resource.section = resource_item['section']['code'] resource.name = resource_item['name'] resource.url = resource_item['url'] resource.save() else: r = models.AquiferResource( url=resource_item['url'], name=resource_item['name'], aquifer=instance, section_id=resource_item['section']['code'].code) r.save() return instance class Meta: model = models.Aquifer fields = ( 'aquifer_id', 'aquifer_name', 'area', 'demand_description', 'demand', 'known_water_use_description', 'known_water_use', 'litho_stratographic_unit', 'location_description', 'mapping_year', 'material_description', 'material', 'notes', 'productivity_description', 'productivity', 'quality_concern_description', 'quality_concern', 'subtype_description', 'subtype', 'vulnerability_description', 'vulnerability', 'resources', )
class StudentDetailSerializer(serializers.ModelSerializer): # we use SlugRelatedField because current_class and current_section are foreign keys in Student Model. Not using # slug related field would return the primary key instead of their respective names current_class = serializers.SlugRelatedField(read_only=True, slug_field='standard') current_section = serializers.SlugRelatedField(read_only=True, slug_field='section') parent = serializers.SlugRelatedField(read_only=True, slug_field='parent_name') parent_mob = serializers.SerializerMethodField() father_occ = serializers.SerializerMethodField() mother_occ = serializers.SerializerMethodField() mother = serializers.SerializerMethodField() mother_mob = serializers.SerializerMethodField() email = serializers.SerializerMethodField() dob = serializers.SerializerMethodField() gender = serializers.SerializerMethodField() blood_group = serializers.SerializerMethodField() adhar = serializers.SerializerMethodField() address = serializers.SerializerMethodField() bus_user = serializers.SerializerMethodField() bus_rout = serializers.SerializerMethodField() bus_stop = serializers.SerializerMethodField() house = serializers.SerializerMethodField() def get_bus_user(self, obj): try: bus_user = BusUser.objects.get(student=obj) print('%s is a bus user' % obj) return 'bus_user' except Exception as e: print('exception 12102019-A from student serializers.py %s %s' % (e.message, type(e))) print('%s is not a bus user' % obj) return 'walker' def get_bus_rout(self, obj): try: rout = Student_Rout.objects.get(student=obj) print('%s is a bus user' % obj) return rout.bus_root.bus_root except Exception as e: print('exception 12102019-B from student serializers.py %s %s' % (e.message, type(e))) print('%s is not a bus user. Hence rout is N/A' % obj) return 'N/A' def get_bus_stop(self, obj): try: rout = Student_Rout.objects.get(student=obj) print('%s is a bus user' % obj) return rout.bus_stop.stop_name except Exception as e: print('exception 12102019-C from student serializers.py %s %s' % (e.message, type(e))) print('%s is not a bus user. Hence bus stop is N/A' % obj) return 'N/A' def get_house(self, obj): try: house = House.objects.get(student=obj) return house.house except Exception as e: print('exception 12102019-D from student serializers.py %s %s' % (e.message, type(e))) print('no house assigned for %s' % obj) return 'Not Assigned' def get_mother(self, obj): try: ad = AdditionalDetails.objects.get(student=obj) return ad.mother_name except Exception as e: print('exception 13102019-A from student serializers.py %s %s' % (e.message, type(e))) print('addtional details (mother) not entered for %s' % obj) return 'Not Available' def get_mother_occ(self, obj): try: ad = AdditionalDetails.objects.get(student=obj) return ad.mother_occupation except Exception as e: print('exception 13102019-H from student serializers.py %s %s' % (e.message, type(e))) print('addtional details (mother occupation) not entered for %s' % obj) return 'Not Available' def get_father_occ(self, obj): try: ad = AdditionalDetails.objects.get(student=obj) return ad.father_occupation except Exception as e: print('exception 13102019-I from student serializers.py %s %s' % (e.message, type(e))) print('addtional details (father occupation) not entered for %s' % obj) return 'Not Available' def get_parent_mob(self, obj): return obj.parent.parent_mobile1 def get_mother_mob(self, obj): return obj.parent.parent_mobile2 def get_email(self, obj): return obj.parent.parent_email def get_dob(self, obj): try: dob = DOB.objects.get(student=obj) return dob.dob except Exception as e: print('exception 13102019-B from student serializers.py %s %s' % (e.message, type(e))) print('DOB not entered for %s' % obj) return 'Not Available' def get_gender(self, obj): try: ad = AdditionalDetails.objects.get(student=obj) return ad.gender except Exception as e: print('exception 13102019-C from student serializers.py %s %s' % (e.message, type(e))) print('addtional details (gender) not entered for %s' % obj) return 'Not Available' def get_blood_group(self, obj): try: ad = AdditionalDetails.objects.get(student=obj) return ad.blood_group except Exception as e: print('exception 13102019-D from student serializers.py %s %s' % (e.message, type(e))) print('addtional details (blood group) not entered for %s' % obj) return 'Not Available' def get_adhar(self, obj): try: ad = AdditionalDetails.objects.get(student=obj) return ad.adhar except Exception as e: print('exception 13102019-E from student serializers.py %s %s' % (e.message, type(e))) print('addtional details (adhar) not entered for %s' % obj) return 'Not Available' def get_address(self, obj): try: ad = AdditionalDetails.objects.get(student=obj) return ad.address except Exception as e: print('exception 13102019-F from student serializers.py %s %s' % (e.message, type(e))) print('addtional details (address) not entered for %s' % obj) return 'Not Available' class Meta: model = Student fields = ('id', 'student_erp_id', 'fist_name', 'last_name', 'roll_number', 'current_class', 'current_section', 'parent', 'parent_mob', 'mother', 'mother_mob', 'email', 'dob', 'gender', 'blood_group', 'adhar', 'address', 'bus_user', 'bus_rout', 'bus_stop', 'house', 'father_occ', 'mother_occ')
class CommentListSerializer(serializers.ModelSerializer): user = serializers.SlugRelatedField(slug_field='name', read_only=True) class Meta: model = models.Comment fields = ('id', 'title', 'text', 'user', 'product', 'createdAt')
class DangerUsedSerializer(serializers.ModelSerializer): """危险物品管理序列化器""" id = serializers.CharField(label='使用记录编号', read_only=True) danger_id = serializers.CharField(label='危险品编号', allow_null=True, write_only=True) # danger = serializers.SlugRelatedField(slug_field='name',read_only=True) danger = DangerSerializer(required=False) manager_id = serializers.CharField(label='负责人id', allow_null=True) manager = serializers.SlugRelatedField(label='负责人', slug_field='name', read_only=True) user_id = serializers.CharField(label='使用人id', allow_null=True, max_length=50) user = serializers.SlugRelatedField(label='使用人', slug_field='name', read_only=True) class Meta: model = DangerUsed exclude = ('create_time', 'update_time') def validate_danger_id(self, value): if Danger.objects.filter(pk=value).count() == 0: raise serializers.ValidationError("危险品不存在") return value def validate_manager(self, value): # 查看人员表中,是否存在该用户 if Staff.objects.filter(name=value).count() == 0: raise serializers.ValidationError("负责人不存在") return value def validate_user(self, value): # 查看人员表中,是否存在该用户 if Staff.objects.filter(name=value).count() == 0: raise serializers.ValidationError("使用人不存在") return value def create(self, validated_data): """新建""" pk = uuid.uuid4() return DangerUsed.objects.create(pk=pk, **validated_data) def update(self, instance, validated_data): """更新,instance为要更新的对象实例""" instance.danger_id = validated_data.get('danger_id', instance.danger_id) instance.manager_id = validated_data.get('manager_id', instance.manager) instance.user_id = validated_data.get('user_id', instance.user) instance.count = validated_data.get('count', instance.count) instance.is_need_back = validated_data.get('is_need_back', instance.is_need_back) instance.is_back = validated_data.get('is_back', instance.is_back) instance.start_time = validated_data.get('start_time', instance.start_time) instance.end_time = validated_data.get('end_time', instance.end_time) instance.save() return instance
class ProjectCommentSerializer(serializers.ModelSerializer): create_user = serializers.SlugRelatedField(queryset=User.objects.all(), slug_field='username') class Meta: model = ProjectComment fields = ('url', 'id', 'project', 'content', 'create_user', 'create_time')
class SectionCreateUpdateSerializer(serializers.ModelSerializer, TranslatableSerializer): """ Serializer for section create/update. """ id = serializers.CharField(required=False) type = serializers.SlugRelatedField(slug_field='identifier', queryset=SectionType.objects.all()) commenting = EnumField(enum_type=Commenting) # this field is used only for incoming data validation, outgoing data is added manually # in to_representation() images = serializers.ListField(child=serializers.DictField(), write_only=True) questions = serializers.ListField(child=serializers.DictField(), write_only=True, required=False) files = serializers.ListField(child=serializers.DictField(), write_only=True, required=False) class Meta: model = Section fields = [ 'id', 'type', 'commenting', 'title', 'abstract', 'content', 'plugin_identifier', 'plugin_data', 'images', 'questions', 'files', 'ordering', ] @transaction.atomic() def create(self, validated_data): images_data = validated_data.pop('images', []) polls_data = validated_data.pop('questions', []) files_data = validated_data.pop('files', []) section = super().create(validated_data) self._handle_images(section, images_data) self._handle_questions(section, polls_data) self._handle_files(section, files_data) return section @transaction.atomic() def update(self, instance, validated_data): images_data = validated_data.pop('images', []) polls_data = validated_data.pop('questions', []) files_data = validated_data.pop('files', []) section = super().update(instance, validated_data) self._handle_images(section, images_data) self._handle_questions(section, polls_data) self._handle_files(section, files_data) return section def validate_images(self, data): for index, image_data in enumerate(data): pk = image_data.get('id') image_data['ordering'] = index serializer_params = {'data': image_data} if pk: try: image = self.instance.images.get(pk=pk) except SectionImage.DoesNotExist: raise ValidationError( 'The Section does not have an image with ID %s' % pk) serializer_params['instance'] = image serializer = SectionImageCreateUpdateSerializer( **serializer_params) serializer.is_valid(raise_exception=True) # save serializer in data so it can be used when handling the images image_data['serializer'] = serializer return data def validate_files(self, data): for index, file_data in enumerate(data): pk = file_data.get('id') file_data['ordering'] = index serializer_params = { 'data': file_data, 'context': { 'request': self.context['request'] } } if pk: try: # only allow orphan files or files within this section already file = SectionFile.objects.filter( Q(section=None) | (Q(section=self.instance))).get(pk=pk) except SectionImage.DoesNotExist: raise ValidationError( 'No file with ID %s available in this section' % pk) serializer_params['instance'] = file serializer = RootFileBase64Serializer(**serializer_params) serializer.is_valid(raise_exception=True) # save serializer in data so it can be used when handling the files file_data['serializer'] = serializer return data def _handle_images(self, section, data): new_image_ids = set() for image_data in data: serializer = image_data.pop('serializer') image = serializer.save(section=section) new_image_ids.add(image.id) for image in section.images.exclude(id__in=new_image_ids): image.soft_delete() return section def _handle_files(self, section, data): new_file_ids = set() for file_data in data: serializer = file_data.pop('serializer') file = serializer.save(section=section) new_file_ids.add(file.id) for file in section.files.exclude(id__in=new_file_ids): file.soft_delete() return section def _validate_question_update(self, poll_data, poll): poll_has_answers = poll.n_answers > 0 if not poll_has_answers: return try: old_poll_data = SectionPollSerializer(poll).data assert compare_serialized(old_poll_data['text'], poll_data['text']) assert len(old_poll_data['options']) == len(poll_data['options']) for old_option, option in zip(old_poll_data['options'], poll_data['options']): assert compare_serialized(old_option['text'], option['text']) except AssertionError: raise ValidationError( 'Poll with ID %s has answers - editing it is not allowed' % repr(poll.pk)) def validate_questions(self, data): for index, poll_data in enumerate(data): pk = poll_data.get('id') poll_data['ordering'] = index + 1 serializer_params = {'data': poll_data} if pk: try: poll = self.instance.polls.get(pk=pk) except SectionPoll.DoesNotExist: raise ValidationError( 'The Section does not have a poll with ID %s' % repr(pk)) self._validate_question_update(poll_data, poll) serializer_params['instance'] = poll serializer = SectionPollSerializer(**serializer_params) serializer.is_valid(raise_exception=True) # save serializer in data so it can be used when handling the polls poll_data['serializer'] = serializer return data def _handle_questions(self, section, data): new_poll_ids = set() for poll_data in data: serializer = poll_data.pop('serializer') poll = serializer.save(section=section, ordering=poll_data['ordering']) new_poll_ids.add(poll.id) for poll in section.polls.exclude(id__in=new_poll_ids): poll.soft_delete() def to_representation(self, instance): data = super().to_representation(instance) data['images'] = SectionImageSerializer( instance.images.all(), many=True, context=self.context, ).data data['questions'] = SectionPollSerializer(instance.polls.all(), many=True).data return data
class MinimalProgramSerializer(serializers.ModelSerializer): authoring_organizations = MinimalOrganizationSerializer(many=True) banner_image = StdImageSerializerField() courses = serializers.SerializerMethodField() type = serializers.SlugRelatedField(slug_field='name', queryset=ProgramType.objects.all()) @classmethod def prefetch_queryset(cls): return Program.objects.all( ).select_related('type', 'partner').prefetch_related( 'excluded_course_runs', # `type` is serialized by a third-party serializer. Providing this field name allows us to # prefetch `applicable_seat_types`, a m2m on `ProgramType`, through `type`, a foreign key to # `ProgramType` on `Program`. 'type__applicable_seat_types', 'authoring_organizations', Prefetch( 'courses', queryset=MinimalProgramCourseSerializer.prefetch_queryset()), ) class Meta: model = Program fields = ( 'uuid', 'title', 'subtitle', 'type', 'status', 'marketing_slug', 'marketing_url', 'banner_image', 'courses', 'authoring_organizations', 'card_image_url', ) read_only_fields = ('uuid', 'marketing_url', 'banner_image') def get_courses(self, program): if program.order_courses_by_start_date: courses, course_runs = self.sort_courses(program) else: courses, course_runs = program.courses.all(), list( program.course_runs) course_serializer = MinimalProgramCourseSerializer( courses, many=True, context={ 'request': self.context.get('request'), 'published_course_runs_only': self.context.get('published_course_runs_only'), 'exclude_utm': self.context.get('exclude_utm'), 'program': program, 'course_runs': course_runs, }) return course_serializer.data def sort_courses(self, program): """ Sorting by enrollment start then by course start yields a list ordered by course start, with ties broken by enrollment start. This works because Python sorting is stable: two objects with equal keys appear in the same order in sorted output as they appear in the input. Courses are only created if there's at least one course run belonging to that course, so course_runs should never be empty. If it is, key functions in this method attempting to find the min of an empty sequence will raise a ValueError. """ course_runs = list(program.course_runs) def min_run_enrollment_start(course): # Enrollment starts may be empty. When this is the case, we make the same assumption as # the LMS: no enrollment_start is equivalent to (offset-aware) datetime.datetime.min. min_datetime = datetime.datetime.min.replace(tzinfo=pytz.UTC) # Course runs excluded from the program are excluded here, too. # # If this becomes a candidate for optimization in the future, be careful sorting null values # in the database. PostgreSQL and MySQL sort null values as if they are higher than non-null # values, while SQLite does the opposite. # # For more, refer to https://docs.djangoproject.com/en/1.10/ref/models/querysets/#latest. _course_runs = [ course_run for course_run in course_runs if course_run.course == course ] # Return early if we have no course runs since min() will fail. if not _course_runs: return min_datetime run = min(_course_runs, key=lambda run: run.enrollment_start or min_datetime) return run.enrollment_start or min_datetime def min_run_start(course): # Course starts may be empty. Since this means the course can't be started, missing course # start date is equivalent to (offset-aware) datetime.datetime.max. max_datetime = datetime.datetime.max.replace(tzinfo=pytz.UTC) _course_runs = [ course_run for course_run in course_runs if course_run.course == course ] # Return early if we have no course runs since min() will fail. if not _course_runs: return max_datetime run = min(_course_runs, key=lambda run: run.start or max_datetime) return run.start or max_datetime courses = list(program.courses.all()) courses.sort(key=min_run_enrollment_start) courses.sort(key=min_run_start) return courses, course_runs
class RunSerializer(AccessControlSerializer, serializers.ModelSerializer): run_status = serializers.HyperlinkedIdentityField(view_name='run-run-status') removal_plan = serializers.HyperlinkedIdentityField(view_name='run-removal-plan') run_outputs = serializers.HyperlinkedIdentityField(view_name='run-run-outputs') sandbox_path = serializers.CharField(read_only=True, required=False) inputs = RunInputSerializer(many=True) stopped_by = serializers.SlugRelatedField( slug_field="username", read_only=True ) runbatch_name = serializers.CharField( source="runbatch.name", read_only=True ) class Meta: model = Run fields = ( 'id', 'url', 'pipeline', 'time_queued', 'start_time', 'end_time', 'name', 'description', 'display_name', 'sandbox_path', 'purged', 'run_status', 'run_outputs', 'removal_plan', 'user', 'users_allowed', 'groups_allowed', 'inputs', 'stopped_by', 'runbatch', 'runbatch_name', 'priority' ) read_only_fields = ( "purged", "time_queued", "start_time", "end_time" ) def validate(self, data): """ Check that the run is correctly specified. First, check that the inputs are correctly specified; then, check that the permissions are OK. """ data = super(RunSerializer, self).validate(data) pipeline = data["pipeline"] posted_input_count = len(data["inputs"]) pipeline_input_count = pipeline.inputs.count() if posted_input_count != pipeline_input_count: raise serializers.ValidationError( 'Pipeline has {} inputs, but only received {}.'.format( pipeline_input_count, posted_input_count)) inputs_sated = [x["index"] for x in data["inputs"]] if len(inputs_sated) != len(set(inputs_sated)): raise serializers.ValidationError( 'Pipeline inputs must be uniquely specified' ) # check range of priority level prio = data.get("priority", 0) if not (0 <= prio <= len(settings.SLURM_QUEUES)): raise serializers.ValidationError("Illegal priority level") errors = RunSerializer.validate_permissions(data) if len(errors) > 0: raise serializers.ValidationError(errors) return data # We don't place this in a transaction; when it's called from a ViewSet, it'll already be # in one. def create(self, validated_data): """ Create a Run to process, i.e. add a job to the work queue. """ return RunSerializer.create_from_validated_data(validated_data) @staticmethod def validate_permissions(data, users_allowed=None, groups_allowed=None): """ Helper used by validate and RunBatch.validate that checks the permissions are OK. If users_allowed and groups_allowed are specified, then they're used instead of the corresponding entries in data. """ # These are lists of users and groups, not usernames and group names. users_allowed = users_allowed or data.get("users_allowed", []) groups_allowed = groups_allowed or data.get("groups_allowed", []) pipeline = data["pipeline"] errors = [] inp_datasets = [] for run_input in data["inputs"]: curr_idx = run_input["index"] curr_SD = run_input["dataset"] try: corresp_input = pipeline.inputs.get(dataset_idx=curr_idx) except TransformationInput.DoesNotExist: errors.append('Pipeline {} has no input with index {}'.format(pipeline, curr_idx)) inp_datasets.append(curr_SD) if curr_SD.is_raw() and corresp_input.is_raw(): continue elif not curr_SD.is_raw() and not corresp_input.is_raw(): if curr_SD.get_cdt().is_restriction(corresp_input.get_cdt()): continue else: errors.append('Input {} is incompatible with Dataset {}'.format(corresp_input, curr_SD)) if len(errors) > 0: raise serializers.ValidationError(errors) # Check Access: that the specified user, users_allowed, and groups_allowed are all okay. all_access_controlled_objects = [pipeline] + inp_datasets users_without_access, groups_without_access = who_cannot_access( data["user"], User.objects.filter(pk__in=[x.pk for x in users_allowed]), Group.objects.filter(pk__in=[x.pk for x in groups_allowed]), all_access_controlled_objects) if len(users_without_access) != 0: errors.append("User(s) {} may not be granted access".format(usrlst2str(users_without_access))) if len(groups_without_access) != 0: errors.append("Group(s) {} may not be granted access".format(grplst2str(groups_without_access))) return errors @staticmethod def create_from_validated_data(validated_data): """ Helper method used by create and also by RunBatchSerializer.create. """ inputs = validated_data.pop("inputs") users_allowed = validated_data.pop("users_allowed", []) groups_allowed = validated_data.pop("groups_allowed", []) # First, create the Run to process with the current time. rtp = Run(time_queued=timezone.now(), **validated_data) rtp.save() rtp.users_allowed.add(*users_allowed) rtp.groups_allowed.add(*groups_allowed) # Create the inputs. for input_data in inputs: rtp.inputs.create(**input_data) # The ViewSet will call full_clean after this, and if it fails then the # transaction will be broken. return rtp
class FlattenedCourseRunWithCourseSerializer(CourseRunSerializer): seats = serializers.SerializerMethodField() owners = serializers.SerializerMethodField() sponsors = serializers.SerializerMethodField() subjects = serializers.SerializerMethodField() prerequisites = serializers.SerializerMethodField() expected_learning_items = serializers.SerializerMethodField() course_key = serializers.SlugRelatedField(read_only=True, source='course', slug_field='key') image = ImageField(read_only=True, source='card_image_url') class Meta: model = CourseRun fields = ( 'key', 'title', 'short_description', 'full_description', 'level_type', 'subjects', 'prerequisites', 'start', 'end', 'enrollment_start', 'enrollment_end', 'announcement', 'seats', 'content_language', 'transcript_languages', 'staff', 'pacing_type', 'min_effort', 'max_effort', 'course_key', 'expected_learning_items', 'image', 'video', 'owners', 'sponsors', 'modified', 'marketing_url', ) def get_seats(self, obj): seats = { 'audit': { 'type': '' }, 'honor': { 'type': '' }, 'verified': { 'type': '', 'currency': '', 'price': '', 'upgrade_deadline': '', }, 'professional': { 'type': '', 'currency': '', 'price': '', 'upgrade_deadline': '', }, 'credit': { 'type': [], 'currency': [], 'price': [], 'upgrade_deadline': [], 'credit_provider': [], 'credit_hours': [], }, } for seat in obj.seats.all(): for key in seats[seat.type].keys(): if seat.type == 'credit': seats['credit'][key].append(SeatSerializer(seat).data[key]) else: seats[seat.type][key] = SeatSerializer(seat).data[key] for credit_attr in seats['credit'].keys(): seats['credit'][credit_attr] = ','.join( [str(e) for e in seats['credit'][credit_attr]]) return seats def get_owners(self, obj): return ','.join( [owner.key for owner in obj.course.authoring_organizations.all()]) def get_sponsors(self, obj): return ','.join([ sponsor.key for sponsor in obj.course.sponsoring_organizations.all() ]) def get_subjects(self, obj): return ','.join( [subject.name for subject in obj.course.subjects.all()]) def get_prerequisites(self, obj): return ','.join([ prerequisite.name for prerequisite in obj.course.prerequisites.all() ]) def get_expected_learning_items(self, obj): return ','.join([ expected_learning_item.value for expected_learning_item in obj.course.expected_learning_items.all() ])
class ProjectSerializer(serializers.ModelSerializer): """The ForAdmins serializer allows editing of the manager field. Other users' serializers do not. Serializer class is determined in the viewset.""" memberships = ProjectMembershipSerializer(read_only=True, many=True) team = serializers.SlugRelatedField(slug_field='slug', read_only=True) manager = ManagerSlugField(slug_field='username', required=False, allow_null=True) # manager = serializers.StringRelatedField(allow_null=True, required=False) url = serializers.SerializerMethodField() tickets_list = serializers.SerializerMethodField() user_permissions = serializers.SerializerMethodField() class Meta: model = Project fields = [ 'title', 'slug', 'description', 'team', 'is_archived', 'manager', 'memberships', 'created', 'modified', 'url', 'tickets_list', 'open_tickets', 'user_permissions', ] read_only_fields = [ 'slug', 'created', 'modified', 'team', 'memberships', 'url', 'tickets_list', 'open_tickets', ] def get_url(self, project): request = self.context.get('request', None) path = reverse_lazy('api:projects-detail', kwargs={ 'team_slug': project.team.slug, 'slug': project.slug }) if request: url = request.build_absolute_uri( str(path) ) # passing string path because reverse_lazy returns a proxy object return url return path def get_user_permissions(self, project): user = self.context.get('request').user return project.get_user_project_permissions(user) def get_tickets_list(self, project): path = reverse('api:tickets-list', kwargs={ 'team_slug': project.team.slug, 'project_slug': project.slug }) request = self.context.get('request') return request.build_absolute_uri(path) def create(self, validated_data): return Project.objects.create_new(**validated_data) def update(self, instance, validated_data): if 'manager' in validated_data: manager = validated_data.pop('manager') instance.make_manager(manager) return super().update(instance, validated_data)
class TaskSerializer(serializers.ModelSerializer): assigned = serializers.SlugRelatedField( slug_field=User.USERNAME_FIELD, required=False, allow_null=True, queryset=User.objects.all()) status_display = serializers.SerializerMethodField() links = serializers.SerializerMethodField() class Meta: model = Task fields = ('id', 'name', 'description', 'sprint', 'status', 'status_display', 'order', 'assigned', 'started', 'due', 'completed', 'links',) def get_status_display(self, obj): return obj.get_status_display() def get_links(self, obj): request = self.context['request'] links = { 'self': reverse('task-detail', kwargs={'pk': obj.pk}, request=request), 'sprint': None, 'assigned': None } if obj.sprint_id: links['sprint'] = reverse('sprint-detail', kwargs={'pk': obj.sprint_id}, request=request) if obj.assigned: links['assigned'] = reverse('user-detail', kwargs={User.USERNAME_FIELD: obj.assigned}, request=request) return links def validate_sprint(self, value): if self.instance and self.instance.pk: if value != self.instance.sprint: if self.instance.status == Task.STATUS_DONE: msg = _('Cannot change the sprint of a completed task.') raise serializers.ValidationError(msg) if value and value.end < date.today(): msg = _('Cannot assign tasks to past sprints.') raise serializers.ValidationError(msg) else: if value and value.end < date.today(): msg = _('Cannot add tasks to past sprints.') raise serializers.ValidationError(msg) return value def validate(self, attrs): sprint = attrs.get('sprint') status = attrs.get('status', Task.STATUS_TODO) started = attrs.get('started') completed = attrs.get('completed') if not sprint and status != Task.STATUS_TODO: msg = _('Backlog tasks must have "Not Started" status.') raise serializers.ValidationError(msg) if started and status == Task.STATUS_TODO: msg = _('Started date cannot be set for not started tasks.') raise serializers.ValidationError(msg) if completed and status != Task.STATUS_DONE: msg = _('Completed date cannot be set for uncompleted tasks.') raise serializers.ValidationError(msg) return attrs
class SnippetValidator(FriendlyErrorMessagesMixin, serializers.Serializer): title = serializers.SlugRelatedField(queryset=Snippet.objects.all(), slug_field='title')
class ProductionInspectionCreateSerializer(serializers.ModelSerializer): production = serializers.SlugRelatedField( many=False, slug_field='slug', queryset=Production.objects.all(), allow_null=False, ) slug = serializers.SlugField(read_only=True, ) state = serializers.IntegerField(read_only=True, ) did_pass = serializers.BooleanField(required=True, ) failure_reason = serializers.CharField( required=False, allow_blank=True, allow_null=True, ) notes = serializers.CharField( required=False, allow_blank=True, allow_null=True, ) crop_inspections = serializers.JSONField(required=True, allow_null=False) class Meta: model = ProductionInspection fields = ( 'production', 'slug', 'state', 'did_pass', 'failure_reason', 'notes', 'crop_inspections', ) def validate_failure_reason(self, value): """ Validation enforces that the `failure_reason` field gets filled out if the user selected `did_pass=True`. """ if self.context.get("did_pass", None) == False: if value == "" or value == None: print( "ProductionInspectionCreateSerializer - validate_failure_reason - failed" ) raise exceptions.ValidationError( _('Please fill in this field.')) return value def create(self, validated_data): # # Get our validated data and context data. user = self.context.get('authenticated_by') ip = self.context.get('authenticated_from') ip_from_is_public = self.context.get('authenticated_from_is_public') production = validated_data.get('production', None) did_pass = validated_data.get('did_pass', None) failure_reason = validated_data.get('failure_reason', None) notes = validated_data.get('notes', None) crop_inspections = validated_data.get('crop_inspections', None) # Step 1: Create our inspection. inspection = ProductionInspection.objects.create( production=production, state=ProductionInspection.STATE.SUBMITTED, did_pass=did_pass, failure_reason=failure_reason, notes=notes, created_by=user, created_from=ip, created_from_is_public=ip_from_is_public, last_modified_by=user, last_modified_from=ip, last_modified_from_is_public=ip_from_is_public, at_duration=production.get_runtime_duration()) # Step 2: Create our crop inspections. self.process_crop_inspections(inspection, user, ip, ip_from_is_public, crop_inspections) # Step 3: Return our created object. return inspection def process_crop_inspections(self, inspection, user, ip, ip_from_is_public, crop_inspections): ''' Function iterates through all the crop inspections we have and serializes them and then saves them to the database. ''' for crop_inspection in crop_inspections: crop_inspection['inspection'] = inspection serializer = ProductionCropInspectionCreateSerializer( data=crop_inspection, context={ 'authenticated_by': user, 'authenticated_from': ip, 'authenticated_from_is_public': ip_from_is_public, 'review': crop_inspection.get('review', None), }) serializer.is_valid(raise_exception=True) validated_data = serializer.save()
class AssetSerializer(BulkOrgResourceModelSerializer): platform = serializers.SlugRelatedField( slug_field='name', queryset=Platform.objects.all(), label=_("Platform") ) protocols = ProtocolsField(label=_('Protocols'), required=False) domain_display = serializers.ReadOnlyField(source='domain.name', label=_('Domain name')) admin_user_display = serializers.ReadOnlyField(source='admin_user.name', label=_('Admin user name')) nodes_display = serializers.ListField(child=serializers.CharField(), label=_('Nodes name'), required=False) """ 资产的数据结构 """ class Meta: model = Asset fields_mini = ['id', 'hostname', 'ip'] fields_small = fields_mini + [ 'protocol', 'port', 'protocols', 'is_active', 'public_ip', 'number', 'vendor', 'model', 'sn', 'cpu_model', 'cpu_count', 'cpu_cores', 'cpu_vcpus', 'memory', 'disk_total', 'disk_info', 'os', 'os_version', 'os_arch', 'hostname_raw', 'comment', 'created_by', 'date_created', 'hardware_info', ] fields_fk = [ 'admin_user', 'admin_user_display', 'domain', 'domain_display', 'platform' ] fk_only_fields = { 'platform': ['name'] } fields_m2m = [ 'nodes', 'nodes_display', 'labels', ] annotates_fields = { # 'admin_user_display': 'admin_user__name' } fields_as = list(annotates_fields.keys()) fields = fields_small + fields_fk + fields_m2m + fields_as read_only_fields = [ 'created_by', 'date_created', ] + fields_as extra_kwargs = { 'protocol': {'write_only': True}, 'port': {'write_only': True}, 'hardware_info': {'label': _('Hardware info')}, 'org_name': {'label': _('Org name')} } @classmethod def setup_eager_loading(cls, queryset): """ Perform necessary eager loading of data. """ queryset = queryset.prefetch_related('admin_user', 'domain', 'platform') queryset = queryset.prefetch_related('nodes', 'labels') return queryset def compatible_with_old_protocol(self, validated_data): protocols_data = validated_data.pop("protocols", []) # 兼容老的api name = validated_data.get("protocol") port = validated_data.get("port") if not protocols_data and name and port: protocols_data.insert(0, '/'.join([name, str(port)])) elif not name and not port and protocols_data: protocol = protocols_data[0].split('/') validated_data["protocol"] = protocol[0] validated_data["port"] = int(protocol[1]) if protocols_data: validated_data["protocols"] = ' '.join(protocols_data) def perform_nodes_display_create(self, instance, nodes_display): if not nodes_display: return nodes_to_set = [] for full_value in nodes_display: node = Node.objects.filter(full_value=full_value).first() if node: nodes_to_set.append(node) else: node = Node.create_node_by_full_value(full_value) nodes_to_set.append(node) instance.nodes.set(nodes_to_set) def create(self, validated_data): self.compatible_with_old_protocol(validated_data) nodes_display = validated_data.pop('nodes_display', '') instance = super().create(validated_data) self.perform_nodes_display_create(instance, nodes_display) return instance def update(self, instance, validated_data): nodes_display = validated_data.pop('nodes_display', '') self.compatible_with_old_protocol(validated_data) instance = super().update(instance, validated_data) self.perform_nodes_display_create(instance, nodes_display) return instance
class EventSerializer(serializers.ModelSerializer): id = serializers.ReadOnlyField() categories = EventCategorySerializer(many=True) occurrences = serializers.SerializerMethodField(read_only=True) rating = serializers.SerializerMethodField(read_only=True) current_user_rating = serializers.SerializerMethodField(read_only=True) schedule = ScheduleSerializer(many=True, write_only=True, allow_empty=False) tags = TagSerializer(many=True, required=False) vacancies = serializers.IntegerField(write_only=True) images = ImageUrlField(read_only=True, many=True) winery = serializers.SlugRelatedField(read_only=True, slug_field='name') contact = serializers.SerializerMethodField(read_only=True) location = serializers.SerializerMethodField(read_only=True) class Meta: model = Event fields = [ 'id', 'name', 'description', 'cancelled', 'price', 'rating', 'current_user_rating', 'tags', 'categories', 'winery', 'occurrences', 'schedule', 'vacancies', 'contact', 'location', 'images', ] def create(self, data): # TODO: finish docstring """Creates and saves an Event associated to instances of EventOcurrence. Params: """ request = self.context.get("request") if request.user.is_anonymous or not request.user.winery: raise serializers.ValidationError('You must have a winery to create events.') schedule = data.pop('schedule') vacancies = data.pop('vacancies') categories = data.pop('categories') tags = data.pop('tags') if 'tags' in data else [] data['winery'] = request.user.winery event = Event.objects.create(**data) for elem in schedule: start_time = elem['start_time'] end_time = elem['end_time'] dates = Event.calculate_dates_in_threshold( elem['from_date'], elem['to_date'], elem['weekdays']) for date in dates: start = datetime.combine(date, start_time) end = datetime.combine(date, end_time) EventOccurrence.objects.create( start=start, end=end, vacancies=vacancies, event=event ) for category in categories: event.categories.add(get_object_or_404(EventCategory, name=category['name'])) for tag in tags: event.tags.add(get_object_or_404(Tag, name=tag['name'])) return event def update(self, instance, validated_data): """Event update method""" instance.name = validated_data.get('name', instance.name) instance.description = validated_data.get('description', instance.description) instance.price = validated_data.get('price', instance.price) vacancies = validated_data.get('vacancies') if vacancies: for elem in validated_data.get('schedule'): start_time = elem['start_time'] end_time = elem['end_time'] dates = Event.calculate_dates_in_threshold( elem['from_date'], elem['to_date'], elem['weekdays']) for date in dates: start = datetime.combine(date, start_time) end = datetime.combine(date, end_time) EventOccurrence.objects.create( start=start, end=end, vacancies=vacancies, event=instance ) categories = validated_data.get('categories') if categories is not None: instance.categories.clear() for category in categories: instance.categories.add(get_object_or_404(EventCategory, name=category['name'])) tags = validated_data.get('tags') if tags is not None: instance.tags.clear() for tag in tags: instance.tags.add(get_object_or_404(Tag, name=tag['name'])) instance.save() return instance def validate_categories(self, categories): """ Check that the categories are valid """ for category in categories: try: EventCategory.objects.get(name=category['name']) except EventCategory.DoesNotExist: raise serializers.ValidationError("category {} does not exist".format(category['name'])) return categories def validate_tags(self, tags): """ Check that the tags are valid """ for tag in tags: try: Tag.objects.get(name=tag['name']) except Tag.DoesNotExist: raise serializers.ValidationError("tag {} does not exist".format(tag['name'])) return tags def validate_vacancies(self, vacancies): if vacancies <= 0: raise serializers.ValidationError('The vacancies must be greater than cero.') return vacancies def validate_schedule(self, schedules): for schedule in schedules: end_date = schedule.get('to_date') start_date = schedule.get('from_date') if not start_date or datetime.now() > datetime.combine(start_date, schedule.get('start_time')): raise serializers.ValidationError({'from_date': 'Invalid start date'}) if end_date and start_date > end_date: raise serializers.ValidationError({'to_date': 'End date must be greater than start date'}) return schedules def validate(self, data): if data.get('schedule') and not data.get('vacancies'): raise serializers.ValidationError({'vacancies': 'Vacancies must be specified'}) return data def get_occurrences(self, event): request = self.context.get('request') user = getattr(request, 'user', None) occurrences = EventOccurrence.objects.filter(event=event) if not (request and getattr(user, 'winery', None) and user.winery == event.winery): occurrences = occurrences.filter( start__gt=datetime.now(), cancelled__isnull=True, ) serializer = VenueSerializer(instance=occurrences, many=True) return serializer.data def get_rating(self, event): rate = Rate.objects.filter(event=event).aggregate(Avg('rate')) return rate['rate__avg'] def get_current_user_rating(self, event): request = self.context.get("request") if not request or request.user.is_anonymous: return None user = request.user rate = Rate.objects.filter(event=event, user=user).first() return RateSerializer(rate).data if rate else None def get_contact(self, event): user = get_user_model().objects.filter(winery=event.winery).first() return {'email': user.email, 'phone_number': user.phone} if user else None def get_location(self, event): if event.winery.location: return json.loads(event.winery.location.json) return None
class PerformanceAlertSummarySerializer(serializers.ModelSerializer): alerts = PerformanceAlertSerializer(many=True, read_only=True) related_alerts = PerformanceAlertSerializer(many=True, read_only=True) performance_tags = serializers.SlugRelatedField( many=True, required=False, slug_field='name', queryset=PerformanceTag.objects.all()) repository = serializers.SlugRelatedField(read_only=True, slug_field='name') framework = serializers.SlugRelatedField(read_only=True, slug_field='id') revision = serializers.SlugRelatedField(read_only=True, slug_field='revision', source='push') push_timestamp = TimestampField(source='push', read_only=True) prev_push_revision = serializers.SlugRelatedField(read_only=True, slug_field='revision', source='prev_push') assignee_username = serializers.SlugRelatedField( slug_field="username", source="assignee", allow_null=True, required=False, queryset=User.objects.all(), ) assignee_email = serializers.SerializerMethodField() # marking these fields as readonly, the user should not be modifying them # (after the item is first created, where we don't use this serializer # class) prev_push_id = serializers.ReadOnlyField() push_id = serializers.ReadOnlyField() created = serializers.ReadOnlyField() def update(self, instance, validated_data): instance.timestamp_first_triage() return super().update(instance, validated_data) def get_assignee_email(self, performance_alert_summary): return getattr(performance_alert_summary.assignee, 'email', None) class Meta: model = PerformanceAlertSummary fields = [ 'id', 'push_id', 'prev_push_id', 'created', 'repository', 'framework', 'alerts', 'related_alerts', 'status', 'bug_number', 'bug_updated', 'issue_tracker', 'notes', 'revision', 'push_timestamp', 'prev_push_revision', 'assignee_username', 'assignee_email', 'performance_tags', ]