diff --git a/SAS/LSMR/src/lsmr/lsmrapp/models/scheduling.py b/SAS/LSMR/src/lsmr/lsmrapp/models/scheduling.py index 179e1fe04006056548890607d0c83bd25904ef0e..193039e0c656fab10a745ed84f59f4054c620fa8 100644 --- a/SAS/LSMR/src/lsmr/lsmrapp/models/scheduling.py +++ b/SAS/LSMR/src/lsmr/lsmrapp/models/scheduling.py @@ -138,7 +138,7 @@ class Subtask(BasicCommon): stop_time = DateTimeField(help_text='Stop this subtask at the specified time (NULLable).') state = ForeignKey('SubtaskStateChoice', null=False, on_delete=PROTECT, related_name='task_states', help_text='Subtask state (see Subtask State Machine).') specifications_doc = JSONField(help_text='Final specifications, as input for the controller.') - task_blueprint = ForeignKey('TaskBlueprint', null=True, on_delete=SET_NULL, help_text='Task Blueprint to which this Subtask belongs.') + task_blueprint = ForeignKey('TaskBlueprint', related_name='subtasks', null=True, on_delete=SET_NULL, help_text='Task Blueprint to which this Subtask belongs.') specifications_template = ForeignKey('SubtaskTemplate', null=False, on_delete=PROTECT, help_text='Schema used for specifications_doc.') do_cancel = DateTimeField(help_text='Timestamp when the subtask has been ordered to cancel (NULLable).') priority = IntegerField(help_text='Absolute priority of this subtask (higher value means more important).') diff --git a/SAS/LSMR/src/lsmr/lsmrapp/models/specification.py b/SAS/LSMR/src/lsmr/lsmrapp/models/specification.py index 2907789d9a3f0dcfa6b6ae4b63ef53773be2324b..1ee9f4a9c62985e8349232d2fd6542241737b1b5 100644 --- a/SAS/LSMR/src/lsmr/lsmrapp/models/specification.py +++ b/SAS/LSMR/src/lsmr/lsmrapp/models/specification.py @@ -189,6 +189,7 @@ class DefaultWorkRelationSelectionTemplate(BasicCommon): # class Cycle(NamedCommon): + start = DateTimeField(help_text='Moment at which the cycle starts, that is, when its projects can run.') stop = DateTimeField(help_text='Moment at which the cycle officially ends.') number = IntegerField(help_text='Cycle number.') @@ -219,7 +220,7 @@ class SchedulingUnitDraft(NamedCommon): copies = ForeignKey('SchedulingUnitDraft', related_name="copied_from", on_delete=SET_NULL, null=True, help_text='Source reference, if we are a copy (NULLable).') copy_reason = ForeignKey('CopyReasonChoice', on_delete=PROTECT, help_text='Reason why source was copied (NULLable).') generator_instance_doc = CharField(max_length=200, help_text='Parameter value that generated this run draft (NULLable).') # todo: check if the field size is good enough - scheduling_set = ForeignKey(SchedulingSet, related_name='scheduling_unit_drafts', on_delete=CASCADE, help_text='Set to which this scheduling unit draft belongs.') + scheduling_set = ForeignKey('SchedulingSet', related_name='scheduling_unit_drafts', on_delete=CASCADE, help_text='Set to which this scheduling unit draft belongs.') requirements_template = ForeignKey(SchedulingUnitTemplate, on_delete=CASCADE, help_text='Schema used for requirements_doc.') # todo: 'schema'? @@ -234,7 +235,7 @@ class TaskDraft(NamedCommon): specifications_doc = JSONField(help_text='Specifications for this task.') copies = ForeignKey('TaskDraft', related_name="copied_from", on_delete=SET_NULL, null=True, help_text='Source reference, if we are a copy (NULLable).') copy_reason = ForeignKey('CopyReasonChoice', on_delete=PROTECT, help_text='Reason why source was copied (NULLable).') - scheduling_unit_draft = ForeignKey(SchedulingUnitDraft, on_delete=CASCADE, help_text='Scheduling Unit draft to which this task draft belongs.') + scheduling_unit_draft = ForeignKey('SchedulingUnitDraft', related_name='task_drafts', on_delete=CASCADE, help_text='Scheduling Unit draft to which this task draft belongs.') specifications_template = ForeignKey('TaskTemplate', on_delete=CASCADE, help_text='Schema used for requirements_doc.') # todo: 'schema'? @@ -263,6 +264,5 @@ class TaskRelationBlueprint(BasicCommon): consumer = ForeignKey(TaskBlueprint, related_name='consumed_by', on_delete=CASCADE, help_text='Task Blueprint that has the input connector.') input = ForeignKey(TaskConnectors, related_name='inputs_task_relation_blueprint', on_delete=CASCADE, help_text='Input connector of consumer.') output = ForeignKey(TaskConnectors, related_name='outputs_task_relation_blueprint', on_delete=CASCADE, help_text='Output connector of producer.') - draft = ForeignKey(TaskRelationDraft, on_delete=CASCADE, help_text='Task Relation Draft which this work request instantiates.') + draft = ForeignKey(TaskRelationDraft, on_delete=CASCADE, related_name='related_task_relation_blueprint', help_text='Task Relation Draft which this work request instantiates.') selection_template = ForeignKey(WorkRelationSelectionTemplate, on_delete=CASCADE, help_text='Schema used for selection_doc.') # todo: 'schema'? - diff --git a/SAS/LSMR/src/lsmr/lsmrapp/serializers/scheduling.py b/SAS/LSMR/src/lsmr/lsmrapp/serializers/scheduling.py index 6c02bccc6a3fef7c6b4e79d896a16b62008b14a4..61a57c496449cd0a1c2bd9f969d94fb8e3e0f047 100644 --- a/SAS/LSMR/src/lsmr/lsmrapp/serializers/scheduling.py +++ b/SAS/LSMR/src/lsmr/lsmrapp/serializers/scheduling.py @@ -4,6 +4,7 @@ This file contains the serializers (for the elsewhere defined data models) from rest_framework import serializers from .. import models +from .specification import RelationalHyperlinkedModelSerializer class SubtaskConnectorSerializer(serializers.HyperlinkedModelSerializer): diff --git a/SAS/LSMR/src/lsmr/lsmrapp/serializers/specification.py b/SAS/LSMR/src/lsmr/lsmrapp/serializers/specification.py index 5ad5f3abcf642f318c677328ad4d16c391e4efe5..c42e0787c9f8eaf04e672b67aa7b7bf9fb010bec 100644 --- a/SAS/LSMR/src/lsmr/lsmrapp/serializers/specification.py +++ b/SAS/LSMR/src/lsmr/lsmrapp/serializers/specification.py @@ -6,6 +6,16 @@ from rest_framework import serializers from .. import models from rest_framework import decorators +class RelationalHyperlinkedModelSerializer(serializers.HyperlinkedModelSerializer): + + def get_field_names(self, declared_fields, info): + expanded_fields = super(RelationalHyperlinkedModelSerializer, self).get_field_names(declared_fields, info) + + if getattr(self.Meta, 'extra_fields', None): + return expanded_fields + self.Meta.extra_fields + else: + return expanded_fields + class TagsSerializer(serializers.HyperlinkedModelSerializer): class Meta: @@ -91,10 +101,11 @@ class TaskConnectorsSerializer(serializers.HyperlinkedModelSerializer): fields = '__all__' -class CycleSerializer(serializers.HyperlinkedModelSerializer): +class CycleSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.Cycle fields = '__all__' + extra_fields = ['projects'] class ProjectSerializer(serializers.HyperlinkedModelSerializer): @@ -103,16 +114,18 @@ class ProjectSerializer(serializers.HyperlinkedModelSerializer): fields = '__all__' -class SchedulingSetSerializer(serializers.HyperlinkedModelSerializer): +class SchedulingSetSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.SchedulingSet fields = '__all__' + extra_fields = ['scheduling_unit_drafts'] -class SchedulingUnitDraftSerializer(serializers.HyperlinkedModelSerializer): +class SchedulingUnitDraftSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.SchedulingUnitDraft fields = '__all__' + extra_fields = ['related_scheduling_unit_blueprint', 'task_drafts'] class SchedulingUnitBlueprintSerializer(serializers.HyperlinkedModelSerializer): @@ -121,34 +134,38 @@ class SchedulingUnitBlueprintSerializer(serializers.HyperlinkedModelSerializer): fields = '__all__' -class TaskDraftSerializer(serializers.HyperlinkedModelSerializer): +class TaskDraftSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.TaskDraft fields = '__all__' + extra_fields = ['related_task_blueprint', 'produced_by', 'consumed_by'] -class TaskBlueprintSerializer(serializers.HyperlinkedModelSerializer): +class TaskBlueprintSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.TaskBlueprint fields = '__all__' + extra_fields = ['subtasks'] -class TaskRelationDraftSerializer(serializers.HyperlinkedModelSerializer): +class TaskRelationDraftSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.TaskRelationDraft fields = '__all__' + extra_fields = ['related_task_relation_blueprint'] -class TaskRelationBlueprintSerializer(serializers.HyperlinkedModelSerializer): +class TaskRelationBlueprintSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.TaskRelationBlueprint fields = '__all__' + extra_fields = ['produced_by', 'consumed_by'] # ----- JSON -class TaskBlueprintSerializerReactJSONform(serializers.HyperlinkedModelSerializer): +class TaskBlueprintSerializerReactJSONform(RelationalHyperlinkedModelSerializer): # Create a JSON editor form to replace the simple text field based on the schema in the template that this # blueprint refers to. If that fails, the JSONField remains a standard text input. @@ -177,9 +194,9 @@ class TaskBlueprintSerializerReactJSONform(serializers.HyperlinkedModelSerialize class Meta: model = models.TaskBlueprint fields = '__all__' + extra_fields = ['subtasks'] - -class TaskBlueprintSerializerJSONeditor(serializers.HyperlinkedModelSerializer): +class TaskBlueprintSerializerJSONeditor(RelationalHyperlinkedModelSerializer): # Create a JSON editor form to replace the simple text field based on the schema in the template that this # blueprint refers to. If that fails, the JSONField remains a standard text input. @@ -208,8 +225,9 @@ class TaskBlueprintSerializerJSONeditor(serializers.HyperlinkedModelSerializer): class Meta: model = models.TaskBlueprint fields = '__all__' + extra_fields = ['subtasks'] -class TaskBlueprintSerializerJSONeditorOnline(serializers.HyperlinkedModelSerializer): +class TaskBlueprintSerializerJSONeditorOnline(RelationalHyperlinkedModelSerializer): # Create a JSON editor form to replace the simple text field based on the schema in the template that this # blueprint refers to. If that fails, the JSONField remains a standard text input. @@ -238,12 +256,12 @@ class TaskBlueprintSerializerJSONeditorOnline(serializers.HyperlinkedModelSerial class Meta: model = models.TaskBlueprint fields = '__all__' + extra_fields = ['subtasks'] -class TaskBlueprintJSONSerializer(serializers.HyperlinkedModelSerializer): +class TaskBlueprintJSONSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.TaskBlueprint fields = ('requirements_doc',) - - + extra_fields = ['subtasks'] \ No newline at end of file