diff --git a/alyx/alyx/base.py b/alyx/alyx/base.py index 83444ffc..bd971157 100644 --- a/alyx/alyx/base.py +++ b/alyx/alyx/base.py @@ -6,7 +6,6 @@ import sys import pytz import uuid -from collections import OrderedDict import one.alf.spec from datetime import datetime import traceback @@ -445,7 +444,7 @@ def ar(self, r, code=200): """ self.assertTrue(r.status_code == code, r.data) pkeys = {'count', 'next', 'previous', 'results'} - if isinstance(r.data, OrderedDict) and set(r.data.keys()) == pkeys: + if isinstance(r.data, dict) and set(r.data.keys()) == pkeys: return r.data['results'] else: return r.data diff --git a/alyx/experiments/models.py b/alyx/experiments/models.py index c0836e22..db42de59 100644 --- a/alyx/experiments/models.py +++ b/alyx/experiments/models.py @@ -181,8 +181,12 @@ class TrajectoryEstimate(models.Model): class Meta: constraints = [ + models.UniqueConstraint(fields=['provenance', 'chronic_insertion'], + condition=models.Q(probe_insertion__isnull=True), + name='unique_trajectory_per_chronic_provenance'), models.UniqueConstraint(fields=['provenance', 'probe_insertion'], - name='unique_trajectory_per_provenance') + condition=models.Q(probe_insertion__isnull=False), + name='unique_trajectory_per_provenance'), ] def __str__(self): diff --git a/alyx/experiments/serializers.py b/alyx/experiments/serializers.py index 0c2c64ec..92ad06a8 100644 --- a/alyx/experiments/serializers.py +++ b/alyx/experiments/serializers.py @@ -27,9 +27,10 @@ class Meta: class TrajectoryEstimateSerializer(serializers.ModelSerializer): probe_insertion = serializers.SlugRelatedField( - read_only=False, required=False, slug_field='id', many=False, + read_only=False, required=False, slug_field='id', many=False, allow_null=True, queryset=ProbeInsertion.objects.all(), ) + x = serializers.FloatField(required=True, allow_null=True) y = serializers.FloatField(required=True, allow_null=True) z = serializers.FloatField(required=False, allow_null=True) @@ -45,6 +46,15 @@ class TrajectoryEstimateSerializer(serializers.ModelSerializer): queryset=CoordinateSystem.objects.all(), ) + def to_internal_value(self, data): + if data.get('chronic_insertion', None) is None: + data['chronic_insertion'] = None + + if data.get('probe_insertion', None) is None: + data['probe_insertion'] = None + + return super(TrajectoryEstimateSerializer, self).to_internal_value(data) + class Meta: model = TrajectoryEstimate fields = '__all__' diff --git a/alyx/experiments/tests_rest.py b/alyx/experiments/tests_rest.py index a717d86f..c2138d1e 100644 --- a/alyx/experiments/tests_rest.py +++ b/alyx/experiments/tests_rest.py @@ -465,7 +465,7 @@ def test_create_list_delete_fov(self): url = reverse('fovlocation-list') with transaction.atomic(): response = self.post(url, loc_dict) - self.ar(response, 500) + self.assertIn(response.status_code, (400, 500)) # In later versions status code is 400 url = reverse('fieldsofview-list') # FOV location containing atlas ID 9 should no longer be default provenance and therefore