diff --git a/SAS/TMSS/backend/test/t_tmssapp_specification_REST_API.py b/SAS/TMSS/backend/test/t_tmssapp_specification_REST_API.py
index 94ebbf8cc8fa57e1c50130baefbe9a60a481b45d..4f39847f316b3f811e81a6b440984c429ff68a1d 100755
--- a/SAS/TMSS/backend/test/t_tmssapp_specification_REST_API.py
+++ b/SAS/TMSS/backend/test/t_tmssapp_specification_REST_API.py
@@ -28,7 +28,7 @@
 # We should probably also fully test behavior wrt mandatory and nullable fields.
 
 from dateutil import parser
-from datetime import datetime
+from datetime import datetime, timedelta
 import unittest
 import logging
 logger = logging.getLogger('lofar.'+__name__)
@@ -1517,8 +1517,8 @@ class SchedulingUnitDraftTestCase(unittest.TestCase):
         Test we can filter on this property, which is explicitly named on the model-specific property filter
         """
         # setup
-        project_1 = models.Project.objects.create(**Project_test_data(name='myproject1_%s' % uuid.uuid4()))
-        project_2 = models.Project.objects.create(**Project_test_data(name='myproject2_%s' % uuid.uuid4()))
+        project_1 = models.Project.objects.create(**Project_test_data(name='myproject_draft_partial_1_%s' % uuid.uuid4()))
+        project_2 = models.Project.objects.create(**Project_test_data(name='myproject_draft_partial_2_%s' % uuid.uuid4()))
         scheduling_set_1 = models.SchedulingSet.objects.create(**SchedulingSet_test_data(project=project_1))
         scheduling_set_2 = models.SchedulingSet.objects.create(**SchedulingSet_test_data(project=project_2))
         su_draft_1 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud1_%s' % uuid.uuid4(), scheduling_set=scheduling_set_1))
@@ -1528,14 +1528,128 @@ class SchedulingUnitDraftTestCase(unittest.TestCase):
         response_1 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?project=%s' % project_1.name, 200)
         response_2 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?project=%s' % project_2.name, 200)
         response_3 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?project=foo', 200)
+        response_4 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?project=myproject_draft_partia', 200)
 
         self.assertEqual(response_1['count'], 1)
         self.assertEqual(response_1['results'][0]['name'], su_draft_1.name)
         self.assertEqual(response_2['count'], 1)
         self.assertEqual(response_2['results'][0]['name'], su_draft_2.name)
         self.assertEqual(response_3['count'], 0)
+        self.assertEqual(response_4['count'], 2)
+        self.assertEqual({response_4['results'][0]['name'], response_4['results'][1]['name']},
+                         {su_draft_1.name, su_draft_2.name})
 
 
+    def test_GET_SchedulingUnitDraft_view_filters_for_id(self):
+        """
+        Test we can filter on this field, which is explicitly named on the model-specific property filter
+        """
+        # setup
+        su_draft_1 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud1_%s' % uuid.uuid4()))
+        su_draft_2 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud2_%s' % uuid.uuid4()))
+        su_draft_3 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud3_%s' % uuid.uuid4()))
+
+        # assert
+        response_1 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?id=%s' % su_draft_1.id, 200)
+        response_2 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?id=%s,%s' % (su_draft_1.id, su_draft_3.id), 200)
+        response_3 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?id=%s' % 999999, 200)
+        response_4 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?id_min=%s&id_max=%s' % (su_draft_2.id, su_draft_3.id), 200)
+
+        self.assertEqual(response_1['count'], 1)
+        self.assertEqual(response_1['results'][0]['name'], su_draft_1.name)
+        self.assertEqual(response_2['count'], 2)
+        self.assertEqual(response_2['results'][0]['name'], su_draft_1.name)
+        self.assertEqual(response_2['results'][1]['name'], su_draft_3.name)
+        self.assertEqual(response_3['count'], 0)
+        self.assertEqual(response_4['count'], 2)
+        self.assertEqual(response_4['results'][0]['name'], su_draft_2.name)
+        self.assertEqual(response_4['results'][1]['name'], su_draft_3.name)
+
+    def test_GET_SchedulingUnitDraft_view_filters_for_blueprints(self):
+        """
+        Test we can filter on this related field, which is explicitly named on the model-specific property filter
+        """
+        # setup
+        models.SchedulingUnitBlueprint.objects.all().delete()
+        models.SchedulingUnitDraft.objects.all().delete()
+        su_draft_1 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud1_%s' % uuid.uuid4()))
+        su_draft_2 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud2_%s' % uuid.uuid4()))
+        su_draft_3 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud3_%s' % uuid.uuid4()))
+        su_blueprint_1 = models.SchedulingUnitBlueprint.objects.create(**SchedulingUnitBlueprint_test_data(name='sub1_%s' % uuid.uuid4(), draft=su_draft_1))
+        su_blueprint_2 = models.SchedulingUnitBlueprint.objects.create(**SchedulingUnitBlueprint_test_data(name='sub2_%s' % uuid.uuid4(), draft=su_draft_2))
+        su_blueprint_3 = models.SchedulingUnitBlueprint.objects.create(**SchedulingUnitBlueprint_test_data(name='sub3_%s' % uuid.uuid4(), draft=su_draft_3))
+
+        # assert
+        response_1 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?scheduling_unit_blueprints=%s' % su_blueprint_1.id, 200)
+        response_2 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?scheduling_unit_blueprints=%s&scheduling_unit_blueprints=%s' % (su_blueprint_1.id, su_blueprint_3.id), 200)
+        response_3 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?scheduling_unit_blueprints=%s' % 999999, 400)
+
+        self.assertEqual(response_1['count'], 1)
+        self.assertEqual(response_1['results'][0]['name'], su_draft_1.name)
+        self.assertEqual(response_2['count'], 2)
+        self.assertEqual(response_2['results'][0]['name'], su_draft_1.name)
+        self.assertEqual(response_2['results'][1]['name'], su_draft_3.name)
+        self.assertIn('Select a valid choice', str(response_3))
+
+    def test_GET_SchedulingUnitDraft_view_filters_for_priority_rank(self):
+        """
+        Test we can filter on this property, which is explicitly named on the model-specific property filter
+        """
+        # setup
+        su_draft_1 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud1_%s' % uuid.uuid4()), priority_rank=0.111)
+        su_draft_2 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud2_%s' % uuid.uuid4()), priority_rank=0.222)
+        su_draft_3 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud3_%s' % uuid.uuid4()), priority_rank=0.333)
+
+        # assert
+        response_1 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?priority_rank_min=%s&priority_rank_max=%s' % (0.110, 0.112), 200)
+        response_2 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?priority_rank_min=%s&priority_rank_max=%s' % (0.2, 0.4), 200)
+
+        self.assertEqual(response_1['count'], 1)
+        self.assertEqual(response_1['results'][0]['name'], su_draft_1.name)
+        self.assertEqual(response_2['count'], 2)
+        self.assertEqual(response_2['results'][0]['name'], su_draft_2.name)
+        self.assertEqual(response_2['results'][1]['name'], su_draft_3.name)
+
+    @unittest.skip('todo: fix this test')
+    def test_GET_SchedulingUnitDraft_view_filters_for_duration(self):
+        """
+        Test we can filter on this property, which is explicitly named on the model-specific property filter
+        """
+        # setup
+        su_draft_1 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud1_%s' % uuid.uuid4()))
+        su_draft_2 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud2_%s' % uuid.uuid4()))
+
+        # assert
+        response_1 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?duration_min=%s&duration_max=%s' % ('1000', '2000'), 200)
+        response_2 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?duration_min=%s&duration_max=%s' % ('-1', '1000'), 200)
+
+        self.assertEqual(response_1['count'], 0)
+        self.assertEqual(response_2['count'], 2)
+        self.assertEqual(response_2['results'][0]['name'], su_draft_1.name)
+        self.assertEqual(response_2['results'][1]['name'], su_draft_2.name)
+
+    def test_GET_SchedulingUnitDraft_view_filters_for_pointing(self):
+        """
+        Test we can filter on this property, which is explicitly named on the model-specific property filter
+        """
+        # setup
+        strategy_template = models.SchedulingUnitObservingStrategyTemplate.objects.get(name="Simple Observation")
+        su_draft_1 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud1_%s' % uuid.uuid4(), observation_strategy_template=strategy_template))
+        su_draft_2 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud2_%s' % uuid.uuid4(), observation_strategy_template=strategy_template))
+
+        su_draft_1.requirements_doc = {'tasks': {'Target Observation': {'specifications_doc': {'SAPs': [{'digital_pointing': {'angle1': 0.333, 'angle2': 0.999, 'direction_type': 'J2000'}}]}}}}
+        su_draft_1.save()
+        su_draft_2.requirements_doc = {'tasks': {'Target Observation': {'specifications_doc': {'SAPs': [{'digital_pointing': {'angle1': 0.111, 'angle2': 0.777, 'direction_type': 'J2000'}}]}}}}
+        su_draft_2.save()
+
+        # assert
+        response_1 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?angle1_min=%s' % 0.222, 200)
+        response_2 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?angle2_max=%s' % 0.888, 200)
+
+        self.assertEqual(response_1['count'], 1)
+        self.assertEqual(response_1['results'][0]['name'], su_draft_1.name)
+        self.assertEqual(response_2['count'], 1)
+        self.assertEqual(response_2['results'][0]['name'], su_draft_2.name)
 
 
 class TaskDraftTestCase(unittest.TestCase):
@@ -2063,8 +2177,8 @@ class SchedulingUnitBlueprintTestCase(unittest.TestCase):
         Test we can filter on this property, which is explicitly named on the model-specific property filter
         """
         # setup
-        project_1 = models.Project.objects.create(**Project_test_data(name='myproject1_%s' % uuid.uuid4()))
-        project_2 = models.Project.objects.create(**Project_test_data(name='myproject2_%s' % uuid.uuid4()))
+        project_1 = models.Project.objects.create(**Project_test_data(name='myproject_partial_1_%s' % uuid.uuid4()))
+        project_2 = models.Project.objects.create(**Project_test_data(name='myproject_partial_2_%s' % uuid.uuid4()))
         scheduling_set_1 = models.SchedulingSet.objects.create(**SchedulingSet_test_data(project=project_1))
         scheduling_set_2 = models.SchedulingSet.objects.create(**SchedulingSet_test_data(project=project_2))
         su_draft_1 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(scheduling_set=scheduling_set_1))
@@ -2076,12 +2190,16 @@ class SchedulingUnitBlueprintTestCase(unittest.TestCase):
         response_1 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?project=%s' % project_1.name, 200)
         response_2 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?project=%s' % project_2.name, 200)
         response_3 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?project=foo', 200)
+        response_4 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?project=myproject_partia', 200)
 
         self.assertEqual(response_1['count'], 1)
         self.assertEqual(response_1['results'][0]['name'], su_blueprint_1.name)
         self.assertEqual(response_2['count'], 1)
         self.assertEqual(response_2['results'][0]['name'], su_blueprint_2.name)
         self.assertEqual(response_3['count'], 0)
+        self.assertEqual(response_4['count'], 2)
+        self.assertEqual(response_4['results'][0]['name'], su_blueprint_1.name)
+        self.assertEqual(response_4['results'][1]['name'], su_blueprint_2.name)
 
     def test_GET_SchedulingUnitBlueprint_view_filters_for_output_pinned(self):
         """
@@ -2103,6 +2221,66 @@ class SchedulingUnitBlueprintTestCase(unittest.TestCase):
         self.assertEqual(response_false['count'], 1)
         self.assertEqual(response_false['results'][0]['name'], su_blueprint_false.name)
 
+    def test_GET_SchedulingUnitBlueprint_view_filters_for_draft(self):
+        """
+        Test we can filter on this property, which is explicitly named on the model-specific property filter
+        """
+        # setup
+        su_draft_1 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud1_%s' % uuid.uuid4()))
+        su_draft_2 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud2_%s' % uuid.uuid4()))
+        su_draft_3 = models.SchedulingUnitDraft.objects.create(**SchedulingUnitDraft_test_data(name='sud3_%s' % uuid.uuid4()))
+        su_blueprint_1 = models.SchedulingUnitBlueprint.objects.create(**SchedulingUnitBlueprint_test_data(name='sub1_%s' % uuid.uuid4()))
+        su_blueprint_2 = models.SchedulingUnitBlueprint.objects.create(**SchedulingUnitBlueprint_test_data(name='sub2_%s' % uuid.uuid4()))
+        su_blueprint_3 = models.SchedulingUnitBlueprint.objects.create(**SchedulingUnitBlueprint_test_data(name='sub3_%s' % uuid.uuid4()))
+        su_blueprint_1.draft = su_draft_1
+        su_blueprint_1.save()
+        su_blueprint_2.draft = su_draft_2
+        su_blueprint_2.save()
+        su_blueprint_3.draft = su_draft_3
+        su_blueprint_3.save()
+
+        # assertresponse_3 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_draft/?scheduling_unit_blueprints=%s' % 999999, 200)
+        response_1 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?draft=%s' % su_draft_1.id, 200)
+        response_2 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?draft=%s,%s' % (su_draft_1.id, su_draft_3.id), 200)
+        response_3 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?draft=%s' % 999999, 400)
+        response_4 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?draft_min=%s&draft_max=%s' % (su_draft_2.id, su_draft_3.id), 200)
+
+        self.assertEqual(response_1['count'], 1)
+        self.assertEqual(response_1['results'][0]['name'], su_blueprint_1.name)
+        self.assertEqual(response_2['count'], 2)
+        self.assertEqual(response_2['results'][0]['name'], su_blueprint_1.name)
+        self.assertEqual(response_2['results'][1]['name'], su_blueprint_3.name)
+        self.assertIn('Select a valid choice', str(response_3))
+        self.assertEqual(response_4['count'], 2)
+        self.assertEqual(response_4['results'][0]['name'], su_blueprint_2.name)
+        self.assertEqual(response_4['results'][1]['name'], su_blueprint_3.name)
+
+
+    def test_GET_SchedulingUnitBlueprint_view_filters_for_id(self):
+        """
+        Test we can filter on this field, which is explicitly named on the model-specific property filter
+        """
+        # setup
+        su_blueprint_1 = models.SchedulingUnitBlueprint.objects.create(**SchedulingUnitBlueprint_test_data(name='sub1_%s' % uuid.uuid4()))
+        su_blueprint_2 = models.SchedulingUnitBlueprint.objects.create(**SchedulingUnitBlueprint_test_data(name='sub2_%s' % uuid.uuid4()))
+        su_blueprint_3 = models.SchedulingUnitBlueprint.objects.create(**SchedulingUnitBlueprint_test_data(name='sub3_%s' % uuid.uuid4()))
+
+        # assert
+        response_1 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?id=%s' % su_blueprint_1.id, 200)
+        response_2 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?id=%s,%s' % (su_blueprint_1.id, su_blueprint_3.id), 200)
+        response_3 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?id=%s' % 999999, 200)
+        response_4 = GET_and_assert_equal_expected_code(self, BASE_URL + '/scheduling_unit_blueprint/?id_min=%s&id_max=%s' % (su_blueprint_2.id, su_blueprint_3.id), 200)
+
+        self.assertEqual(response_1['count'], 1)
+        self.assertEqual(response_1['results'][0]['name'], su_blueprint_1.name)
+        self.assertEqual(response_2['count'], 2)
+        self.assertEqual(response_2['results'][0]['name'], su_blueprint_1.name)
+        self.assertEqual(response_2['results'][1]['name'], su_blueprint_3.name)
+        self.assertEqual(response_3['count'], 0)
+        self.assertEqual(response_4['count'], 2)
+        self.assertEqual(response_4['results'][0]['name'], su_blueprint_2.name)
+        self.assertEqual(response_4['results'][1]['name'], su_blueprint_3.name)
+
 
 class TaskBlueprintTestCase(unittest.TestCase):
     @classmethod