From 06993aeb9b253d250f193d7fef4ea55e76da6e9c Mon Sep 17 00:00:00 2001 From: Mattia Mancini <mancini@astron.nl> Date: Fri, 6 Jul 2018 08:33:11 +0000 Subject: [PATCH] Story LSMR-13: Implementing directory structure to support additional models/serializers/viewsets --- .gitattributes | 9 + SAS/LSMR/src/lsmr/lsmrapp/CMakeLists.txt | 8 +- .../src/lsmr/lsmrapp/models/CMakeLists.txt | 10 ++ SAS/LSMR/src/lsmr/lsmrapp/models/__init__.py | 1 + .../src/lsmr/lsmrapp/models/specification.py | 161 ++++++++++++++++++ .../lsmr/lsmrapp/serializers/CMakeLists.txt | 11 ++ .../src/lsmr/lsmrapp/serializers/__init__.py | 1 + .../lsmr/lsmrapp/serializers/specification.py | 43 +++++ .../src/lsmr/lsmrapp/viewsets/CMakeLists.txt | 10 ++ .../src/lsmr/lsmrapp/viewsets/__init__.py | 1 + .../lsmr/lsmrapp/viewsets/specification.py | 36 ++++ 11 files changed, 287 insertions(+), 4 deletions(-) create mode 100644 SAS/LSMR/src/lsmr/lsmrapp/models/CMakeLists.txt create mode 100644 SAS/LSMR/src/lsmr/lsmrapp/models/__init__.py create mode 100644 SAS/LSMR/src/lsmr/lsmrapp/models/specification.py create mode 100644 SAS/LSMR/src/lsmr/lsmrapp/serializers/CMakeLists.txt create mode 100644 SAS/LSMR/src/lsmr/lsmrapp/serializers/__init__.py create mode 100644 SAS/LSMR/src/lsmr/lsmrapp/serializers/specification.py create mode 100644 SAS/LSMR/src/lsmr/lsmrapp/viewsets/CMakeLists.txt create mode 100644 SAS/LSMR/src/lsmr/lsmrapp/viewsets/__init__.py create mode 100644 SAS/LSMR/src/lsmr/lsmrapp/viewsets/specification.py diff --git a/.gitattributes b/.gitattributes index 0149603c934..eb1a1acda27 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4249,8 +4249,17 @@ SAS/LSMR/src/lsmr/lsmrapp/migrations/0002_auto_20180705_0736.py -text SAS/LSMR/src/lsmr/lsmrapp/migrations/CMakeLists.txt -text SAS/LSMR/src/lsmr/lsmrapp/migrations/__init__.py -text SAS/LSMR/src/lsmr/lsmrapp/models.py -text +SAS/LSMR/src/lsmr/lsmrapp/models/CMakeLists.txt -text +SAS/LSMR/src/lsmr/lsmrapp/models/__init__.py -text +SAS/LSMR/src/lsmr/lsmrapp/models/specification.py -text SAS/LSMR/src/lsmr/lsmrapp/serializers.py -text +SAS/LSMR/src/lsmr/lsmrapp/serializers/CMakeLists.txt -text +SAS/LSMR/src/lsmr/lsmrapp/serializers/__init__.py -text +SAS/LSMR/src/lsmr/lsmrapp/serializers/specification.py -text SAS/LSMR/src/lsmr/lsmrapp/viewsets.py -text +SAS/LSMR/src/lsmr/lsmrapp/viewsets/CMakeLists.txt -text +SAS/LSMR/src/lsmr/lsmrapp/viewsets/__init__.py -text +SAS/LSMR/src/lsmr/lsmrapp/viewsets/specification.py -text SAS/LSMR/src/lsmr/settings.py -text SAS/LSMR/src/lsmr/urls.py -text SAS/LSMR/src/lsmr/wsgi.py -text diff --git a/SAS/LSMR/src/lsmr/lsmrapp/CMakeLists.txt b/SAS/LSMR/src/lsmr/lsmrapp/CMakeLists.txt index eb5a82448aa..06facde1f65 100644 --- a/SAS/LSMR/src/lsmr/lsmrapp/CMakeLists.txt +++ b/SAS/LSMR/src/lsmr/lsmrapp/CMakeLists.txt @@ -5,13 +5,13 @@ set(_py_files __init__.py admin.py apps.py - models.py - viewsets.py - serializers.py ) python_install(${_py_files} DESTINATION lofar/sas/lsmr/lsmr/lsmrapp) -add_subdirectory(migrations) \ No newline at end of file +add_subdirectory(migrations) +add_subdirectory(models) +add_subdirectory(serializers) +add_subdirectory(viewsets) diff --git a/SAS/LSMR/src/lsmr/lsmrapp/models/CMakeLists.txt b/SAS/LSMR/src/lsmr/lsmrapp/models/CMakeLists.txt new file mode 100644 index 00000000000..ddb94230c05 --- /dev/null +++ b/SAS/LSMR/src/lsmr/lsmrapp/models/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(PythonInstall) + +set(_py_files + __init__.py + specification.py + ) + +python_install(${_py_files} + DESTINATION lofar/sas/lsmr/lsmr/lsmrapp/models) diff --git a/SAS/LSMR/src/lsmr/lsmrapp/models/__init__.py b/SAS/LSMR/src/lsmr/lsmrapp/models/__init__.py new file mode 100644 index 00000000000..9e8eba30f25 --- /dev/null +++ b/SAS/LSMR/src/lsmr/lsmrapp/models/__init__.py @@ -0,0 +1 @@ +from .specification import * \ No newline at end of file diff --git a/SAS/LSMR/src/lsmr/lsmrapp/models/specification.py b/SAS/LSMR/src/lsmr/lsmrapp/models/specification.py new file mode 100644 index 00000000000..a7c28a13ef2 --- /dev/null +++ b/SAS/LSMR/src/lsmr/lsmrapp/models/specification.py @@ -0,0 +1,161 @@ +""" +This file contains the database models +""" + +from django.db.models import Model, CharField, DateTimeField, BooleanField, ForeignKey, CASCADE, Field +from django.contrib.postgres.fields import ArrayField, JSONField +from django.contrib.postgres.indexes import GinIndex +from enum import Enum + + +# +# Common +# + +# abstract models + +class BasicCommon(Model): + # todo: we cannot use foreign keys in the array here, so we have to keep the Tags table up to date by trigger or so. + # todo: we could switch to a manytomany field instead? + tags = ArrayField(CharField(max_length=30), size=8, blank=True) + creation = DateTimeField(auto_now_add=True) + update = DateTimeField(auto_now=True) + + class Meta: + abstract = True + indexes = [GinIndex(fields=['tags'])] + + +class UserDefinedCommon(BasicCommon): + name = CharField(max_length=30) + + class Meta: + abstract = True + + +class SystemDefinedCommon(BasicCommon): + + class Meta: + abstract = True + + +# concrete models + +class Tags(Model): + # todo: figure out how to keep this in sync with tags columns (->BasicCommon) + # todo: Or remove this altogether without keeping track of tags? + title = CharField(max_length=30) + description = CharField(max_length=255) + + +# +# I/O +# + +# enums + +class RoleChoice(Enum): + CORRELATOR = "correlator" + BEAMFORMER = "beamformer" + INSPECTION_PLOTS = "inspection plots" + CALIBRATOR = "calibrator" + TARGET = "target" + INPUT_OUTPUT = "input, output" + + +class DatatypeChoice(Enum): + VISIBILITIES = "visibilities" + TIME_SERIES = "time series" + INSTRUMENT_MODEL = "instrument model" + IMAGE = "image" + QUALITY = "quality" + + +class DataformatChoice(Enum): + MEASUREMENTSET = "MeasurementSet" + HDF5 = "HDF5" + + +# todo: fix this! +#class EnumField(Field): # todo: Test if CharField works better e.g. for forms +# """ +# Django does not support creating db enums, so we got to do that ourselves here +# """ +# def __init__(self, *args, **kwargs): +# super(EnumField, self).__init__(*args, **kwargs) +# +# def db_type(self, connection): +# return "enum(%s)" % ','.join("'%s'" % key for (key, _) in self.choices) +# # todo: unfortunately this won't work for Postgres since a CREATE TYPE is required first... + + +# concrete models + +class WorkIORoles(Model): + # todo: Choices do not translate to a Postgres ENUM type currently, but are only enforced on the Django level. + # todo: If we are not happy with this as is, I see two options: + # todo: 1. Wait to see if they implement that EnumField in the meantime (https://code.djangoproject.com/ticket/24342) + # todo: 2. Build this ourselves. I tried to achieve that with the EnumField above, but it won't be that easy, I guess + role = CharField( + max_length=30, + choices=[(item.name, item.value) for item in RoleChoice] + ) + datatype = CharField( + max_length=30, + choices=[(item.name, item.value) for item in DatatypeChoice] + ) + dataformat = ArrayField(CharField( + max_length=30, + choices=[(item.name, item.value) for item in DataformatChoice] + ), size=8, blank=True) + outputs = ForeignKey("WorkRequestTemplate", related_name='role_output', on_delete=CASCADE, null=True) + inputs = ForeignKey("WorkRequestTemplate", related_name='role_input', on_delete=CASCADE, null=True) + + +# +# Templates +# + +# abstract models + +class Template(SystemDefinedCommon): + name = CharField(max_length=30) # todo: check if this should go in SystemDefinedCommon or BasicCommon + description = CharField(max_length=255) # todo: check if this should go in SystemDefinedCommon or BasicCommon + default_version = BooleanField() + version = CharField(max_length=30) + schema = JSONField() + + class Meta: + abstract = True + #unique_together = ("name", "default_version") # todo: We only want this for default_version=True, find a way to do so + + +# concrete models + +class GeneratorTemplate(Template): + create_func = CharField(max_length=30) + + +class RunTemplate(Template): + pass + + +class WorkRequestTemplate(Template): + validation_code_js = CharField(max_length=30) + # outputs = ForeignKey("WorkIORoles", related_name='role_output', on_delete=CASCADE) # todo: removed in latest draft, delete? + # inputs = ForeignKey("WorkIORoles", related_name='role_input', on_delete=CASCADE) # todo: removed in latest draft, delete? + + +class WorkRelationSelectionTemplate(Template): + pass + + + + +# +# Instance Objects +# + +# todo: the blue stuff +# run / work request / work request relation -> SystemDefinedCommon +# others -> UserDefinedCommon \ No newline at end of file diff --git a/SAS/LSMR/src/lsmr/lsmrapp/serializers/CMakeLists.txt b/SAS/LSMR/src/lsmr/lsmrapp/serializers/CMakeLists.txt new file mode 100644 index 00000000000..c1cdf544c20 --- /dev/null +++ b/SAS/LSMR/src/lsmr/lsmrapp/serializers/CMakeLists.txt @@ -0,0 +1,11 @@ + +include(PythonInstall) + +set(_py_files + __init__.py + specification.py + + ) + +python_install(${_py_files} + DESTINATION lofar/sas/lsmr/lsmr/lsmrapp/serializers) diff --git a/SAS/LSMR/src/lsmr/lsmrapp/serializers/__init__.py b/SAS/LSMR/src/lsmr/lsmrapp/serializers/__init__.py new file mode 100644 index 00000000000..9e8eba30f25 --- /dev/null +++ b/SAS/LSMR/src/lsmr/lsmrapp/serializers/__init__.py @@ -0,0 +1 @@ +from .specification import * \ No newline at end of file diff --git a/SAS/LSMR/src/lsmr/lsmrapp/serializers/specification.py b/SAS/LSMR/src/lsmr/lsmrapp/serializers/specification.py new file mode 100644 index 00000000000..9b70a05d1b0 --- /dev/null +++ b/SAS/LSMR/src/lsmr/lsmrapp/serializers/specification.py @@ -0,0 +1,43 @@ +""" +This file contains the serializers (for the elsewhere defined data models) +""" + +from rest_framework import serializers +from lsmr.lsmrapp import models + + +class TagsSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = models.Tags + fields = '__all__' + + +class GeneratorTemplateSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = models.GeneratorTemplate + fields = '__all__' + + +class RunTemplateSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = models.RunTemplate + fields = '__all__' + + +class WorkRequestTemplateSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = models.WorkRequestTemplate + fields = '__all__' + + +class WorkRelationSelectionTemplateSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = models.WorkRelationSelectionTemplate + fields = '__all__' + + +class WorkIORolesSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = models.WorkIORoles + fields = '__all__' + diff --git a/SAS/LSMR/src/lsmr/lsmrapp/viewsets/CMakeLists.txt b/SAS/LSMR/src/lsmr/lsmrapp/viewsets/CMakeLists.txt new file mode 100644 index 00000000000..65ce74a51a2 --- /dev/null +++ b/SAS/LSMR/src/lsmr/lsmrapp/viewsets/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(PythonInstall) + +set(_py_files + __init__.py + specification.py + ) + +python_install(${_py_files} + DESTINATION lofar/sas/lsmr/lsmr/lsmrapp/viewsets) diff --git a/SAS/LSMR/src/lsmr/lsmrapp/viewsets/__init__.py b/SAS/LSMR/src/lsmr/lsmrapp/viewsets/__init__.py new file mode 100644 index 00000000000..9e8eba30f25 --- /dev/null +++ b/SAS/LSMR/src/lsmr/lsmrapp/viewsets/__init__.py @@ -0,0 +1 @@ +from .specification import * \ No newline at end of file diff --git a/SAS/LSMR/src/lsmr/lsmrapp/viewsets/specification.py b/SAS/LSMR/src/lsmr/lsmrapp/viewsets/specification.py new file mode 100644 index 00000000000..ce4aff6ec8c --- /dev/null +++ b/SAS/LSMR/src/lsmr/lsmrapp/viewsets/specification.py @@ -0,0 +1,36 @@ +""" +This file contains the viewsets (based on the elsewhere defined data models and serializers) +""" + +from rest_framework import viewsets +from lsmr.lsmrapp import models, serializers + + +class TagsViewSet(viewsets.ModelViewSet): + queryset = models.Tags.objects.all() + serializer_class = serializers.TagsSerializer + + +class GeneratorTemplateViewSet(viewsets.ModelViewSet): + queryset = models.GeneratorTemplate.objects.all() + serializer_class = serializers.GeneratorTemplateSerializer + + +class RunTemplateViewSet(viewsets.ModelViewSet): + queryset = models.RunTemplate.objects.all() + serializer_class = serializers.RunTemplateSerializer + + +class WorkRequestTemplateViewSet(viewsets.ModelViewSet): + queryset = models.WorkRequestTemplate.objects.all() + serializer_class = serializers.WorkRequestTemplateSerializer + + +class WorkRelationSelectionTemplateViewSet(viewsets.ModelViewSet): + queryset = models.WorkRelationSelectionTemplate.objects.all() + serializer_class = serializers.WorkRelationSelectionTemplateSerializer + + +class WorkIORolesViewSet(viewsets.ModelViewSet): + queryset = models.WorkIORoles.objects.all() + serializer_class = serializers.WorkIORolesSerializer -- GitLab