Skip to content
Snippets Groups Projects
Commit 00d3177e authored by Jorrit Schaap's avatar Jorrit Schaap
Browse files

TMSS-206: just return a QuerySet for the properties successors and predecessors.

parent a328152d
No related branches found
No related tags found
1 merge request!158Resolve TMSS-206
...@@ -7,7 +7,7 @@ import logging ...@@ -7,7 +7,7 @@ import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from django.db.models import ForeignKey, CharField, DateTimeField, BooleanField, IntegerField, BigIntegerField, \ from django.db.models import ForeignKey, CharField, DateTimeField, BooleanField, IntegerField, BigIntegerField, \
ManyToManyField, CASCADE, SET_NULL, PROTECT, UniqueConstraint ManyToManyField, CASCADE, SET_NULL, PROTECT, UniqueConstraint, QuerySet
from django.contrib.postgres.fields import ArrayField, JSONField from django.contrib.postgres.fields import ArrayField, JSONField
from django.contrib.auth.models import User from django.contrib.auth.models import User
from .specification import AbstractChoice, BasicCommon, Template, NamedCommon # , <TaskBlueprint from .specification import AbstractChoice, BasicCommon, Template, NamedCommon # , <TaskBlueprint
...@@ -174,8 +174,10 @@ class Subtask(BasicCommon): ...@@ -174,8 +174,10 @@ class Subtask(BasicCommon):
tobus.send(msg) tobus.send(msg)
@property @property
def successors_queryset(self): def successors(self) -> QuerySet:
'''return the connect successor subtask(s) as queryset (over which you can perform extended queries, or return via the serializers/viewsets)''' '''return the connect successor subtask(s) as queryset (over which you can perform extended queries, or return via the serializers/viewsets)
If you want the result, add .all() like so: my_subtask.successors.all()
'''
# JS, 20200528: I couldn't make django do a "self-reference" query from the subtask table to the subtask table (via input, output), so I used plain SQL. # JS, 20200528: I couldn't make django do a "self-reference" query from the subtask table to the subtask table (via input, output), so I used plain SQL.
return Subtask.objects.filter(id__in=RawSQL("SELECT successor_st.id FROM tmssapp_subtask as successor_st\n" return Subtask.objects.filter(id__in=RawSQL("SELECT successor_st.id FROM tmssapp_subtask as successor_st\n"
"INNER JOIN tmssapp_subtaskinput as st_input on st_input.subtask_id = successor_st.id\n" "INNER JOIN tmssapp_subtaskinput as st_input on st_input.subtask_id = successor_st.id\n"
...@@ -183,24 +185,16 @@ class Subtask(BasicCommon): ...@@ -183,24 +185,16 @@ class Subtask(BasicCommon):
"WHERE st_output.subtask_id = %s", params=[self.id])) "WHERE st_output.subtask_id = %s", params=[self.id]))
@property @property
def successors(self): def predecessors(self) -> QuerySet:
'''return the connect successor subtask(s) as result of successors_queryset''' '''return the connect predecessor subtask(s) as queryset (over which you can perform extended queries, or return via the serializers/viewsets)
return self.successors_queryset.all() If you want the result, add .all() like so: my_subtask.predecessors.all()
'''
@property
def predecessors_queryset(self):
'''return the connect predecessor subtask(s) as queryset (over which you can perform extended queries, or return via the serializers/viewsets)'''
# JS, 20200528: I couldn't make django do a "self-reference" query from the subtask table to the subtask table (via input, output), so I used plain SQL. # JS, 20200528: I couldn't make django do a "self-reference" query from the subtask table to the subtask table (via input, output), so I used plain SQL.
return Subtask.objects.filter(id__in=RawSQL("SELECT predecessor_st.id FROM tmssapp_subtask as predecessor_st\n" return Subtask.objects.filter(id__in=RawSQL("SELECT predecessor_st.id FROM tmssapp_subtask as predecessor_st\n"
"INNER JOIN tmssapp_subtaskoutput as st_output on st_output.subtask_id = predecessor_st.id\n" "INNER JOIN tmssapp_subtaskoutput as st_output on st_output.subtask_id = predecessor_st.id\n"
"INNER JOIN tmssapp_subtaskinput as st_input on st_input.producer_id = st_output.id\n" "INNER JOIN tmssapp_subtaskinput as st_input on st_input.producer_id = st_output.id\n"
"WHERE st_input.subtask_id = %s", params=[self.id])) "WHERE st_input.subtask_id = %s", params=[self.id]))
@property
def predecessors(self):
'''return the connect predecessor subtask(s) as result of predecessors_queryset'''
return self.predecessors_queryset.all()
def save(self, force_insert=False, force_update=False, using=None, update_fields=None): def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
creating = self._state.adding # True on create, False on update creating = self._state.adding # True on create, False on update
......
...@@ -198,10 +198,10 @@ class SubtaskNestedViewSet(LOFARNestedViewSet): ...@@ -198,10 +198,10 @@ class SubtaskNestedViewSet(LOFARNestedViewSet):
subtask = get_object_or_404(models.Subtask, pk=self.kwargs['subtask_id']) subtask = get_object_or_404(models.Subtask, pk=self.kwargs['subtask_id'])
if 'successors' in self.request._request.path: if 'successors' in self.request._request.path:
return subtask.successors_queryset return subtask.successors
if 'predecessors' in self.request._request.path: if 'predecessors' in self.request._request.path:
return subtask.predecessors_queryset return subtask.predecessors
class SubtaskInputViewSet(LOFARViewSet): class SubtaskInputViewSet(LOFARViewSet):
queryset = models.SubtaskInput.objects.all() queryset = models.SubtaskInput.objects.all()
......
...@@ -215,10 +215,10 @@ class SubtaskTest(unittest.TestCase): ...@@ -215,10 +215,10 @@ class SubtaskTest(unittest.TestCase):
subtask1:models.Subtask = models.Subtask.objects.create(**Subtask_test_data()) subtask1:models.Subtask = models.Subtask.objects.create(**Subtask_test_data())
subtask2:models.Subtask = models.Subtask.objects.create(**Subtask_test_data()) subtask2:models.Subtask = models.Subtask.objects.create(**Subtask_test_data())
self.assertEqual(set(), set(subtask1.predecessors)) self.assertEqual(set(), set(subtask1.predecessors.all()))
self.assertEqual(set(), set(subtask2.predecessors)) self.assertEqual(set(), set(subtask2.predecessors.all()))
self.assertEqual(set(), set(subtask1.successors)) self.assertEqual(set(), set(subtask1.successors.all()))
self.assertEqual(set(), set(subtask2.successors)) self.assertEqual(set(), set(subtask2.successors.all()))
def test_Subtask_predecessors_and_successors_simple(self): def test_Subtask_predecessors_and_successors_simple(self):
subtask1:models.Subtask = models.Subtask.objects.create(**Subtask_test_data()) subtask1:models.Subtask = models.Subtask.objects.create(**Subtask_test_data())
...@@ -227,8 +227,8 @@ class SubtaskTest(unittest.TestCase): ...@@ -227,8 +227,8 @@ class SubtaskTest(unittest.TestCase):
output1 = models.SubtaskOutput.objects.create(subtask=subtask1) output1 = models.SubtaskOutput.objects.create(subtask=subtask1)
models.SubtaskInput.objects.create(**SubtaskInput_test_data(subtask=subtask2, producer=output1)) models.SubtaskInput.objects.create(**SubtaskInput_test_data(subtask=subtask2, producer=output1))
self.assertEqual(subtask1, subtask2.predecessors[0]) self.assertEqual(subtask1, subtask2.predecessors.all()[0])
self.assertEqual(subtask2, subtask1.successors[0]) self.assertEqual(subtask2, subtask1.successors.all()[0])
def test_Subtask_predecessors_and_successors_complex(self): def test_Subtask_predecessors_and_successors_complex(self):
subtask1:models.Subtask = models.Subtask.objects.create(**Subtask_test_data()) subtask1:models.Subtask = models.Subtask.objects.create(**Subtask_test_data())
...@@ -255,16 +255,16 @@ class SubtaskTest(unittest.TestCase): ...@@ -255,16 +255,16 @@ class SubtaskTest(unittest.TestCase):
models.SubtaskInput.objects.create(**SubtaskInput_test_data(subtask=subtask5, producer=output3)) models.SubtaskInput.objects.create(**SubtaskInput_test_data(subtask=subtask5, producer=output3))
models.SubtaskInput.objects.create(**SubtaskInput_test_data(subtask=subtask6, producer=output5)) models.SubtaskInput.objects.create(**SubtaskInput_test_data(subtask=subtask6, producer=output5))
self.assertEqual(set((subtask1, subtask2)), set(subtask3.predecessors)) self.assertEqual(set((subtask1, subtask2)), set(subtask3.predecessors.all()))
self.assertEqual(set((subtask4, subtask5)), set(subtask3.successors)) self.assertEqual(set((subtask4, subtask5)), set(subtask3.successors.all()))
self.assertEqual(set((subtask3,)), set(subtask4.predecessors)) self.assertEqual(set((subtask3,)), set(subtask4.predecessors.all()))
self.assertEqual(set((subtask3,)), set(subtask5.predecessors)) self.assertEqual(set((subtask3,)), set(subtask5.predecessors.all()))
self.assertEqual(set((subtask3,)), set(subtask1.successors)) self.assertEqual(set((subtask3,)), set(subtask1.successors.all()))
self.assertEqual(set((subtask3,)), set(subtask2.successors)) self.assertEqual(set((subtask3,)), set(subtask2.successors.all()))
self.assertEqual(set(), set(subtask1.predecessors)) self.assertEqual(set(), set(subtask1.predecessors.all()))
self.assertEqual(set(), set(subtask2.predecessors)) self.assertEqual(set(), set(subtask2.predecessors.all()))
self.assertEqual(set(), set(subtask4.successors)) self.assertEqual(set(), set(subtask4.successors.all()))
self.assertEqual(set((subtask6,)), set(subtask5.successors)) self.assertEqual(set((subtask6,)), set(subtask5.successors.all()))
class DataproductTest(unittest.TestCase): class DataproductTest(unittest.TestCase):
def test_Dataproduct_gets_created_with_correct_creation_timestamp(self): def test_Dataproduct_gets_created_with_correct_creation_timestamp(self):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment