예제 #1
0
class PostSerializer(serializers.ModelSerializer):
    tags = serializers.SlugRelatedField(many=True, slug_field='label', queryset=Tag.objects.all())

    class Meta:
        model = Post
        exclude = []
예제 #2
0
class AddressSerializer(serializers.ModelSerializer):
    user = serializers.SlugRelatedField(queryset=User.objects.all(),
                                        slug_field='username')

    class Meta:
        model = Address
예제 #3
0
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)
예제 #4
0
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',
        )
예제 #5
0
class CreateFavoriteSerializer(serializers.Serializer):
    offer = serializers.SlugRelatedField(slug_field='uuid',
                                         queryset=Offer.objects.all())
예제 #6
0
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
예제 #7
0
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))
예제 #8
0
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
예제 #9
0
class CommentSerializer(serializers.ModelSerializer):
    author = serializers.SlugRelatedField(slug_field="username", read_only=True)

    class Meta:
        model = Comment
        fields = "__all__"
예제 #10
0
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
            },
        }
예제 #11
0
    class FavoriteListSerializer(serializers.ModelSerializer):
        post_id = serializers.SlugRelatedField(read_only=True, slug_field='id')

        class Meta:
            model = Favorite
            fields = ['post_id']
예제 #12
0
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}}
예제 #13
0
class BookingSerializer(serializers.ModelSerializer):
	flight = serializers.SlugRelatedField(slug_field='destination', read_only=True)

	class Meta:
		model = Booking
		fields = ['flight', 'date', 'id']
예제 #14
0
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)
예제 #15
0
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',
        )
예제 #16
0
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')
예제 #18
0
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
예제 #19
0
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')
예제 #20
0
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
예제 #21
0
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
예제 #22
0
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
예제 #23
0
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()
        ])
예제 #24
0
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)
예제 #25
0
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')
예제 #27
0
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()
예제 #28
0
파일: asset.py 프로젝트: zpl0404/jumpserver
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
예제 #29
0
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
예제 #30
0
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',
        ]