Skip to content

Commit 5845daa

Browse files
authored
Merge pull request #428 from hburgund/speaker-relationships
Speaker relationships for looping recording and playback projects
2 parents 81e4f60 + e73ac96 commit 5845daa

7 files changed

Lines changed: 52 additions & 4 deletions

File tree

roundware/api2/filters.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,14 @@ class Meta:
242242
class SpeakerFilterSet(django_filters.FilterSet):
243243
activeyn = django_filters.TypedChoiceFilter(choices=BOOLEAN_CHOICES, coerce=strtobool)
244244
project_id = django_filters.NumberFilter()
245+
parent_ids_or = IntegerListFilter(field_name='parents', lookup_expr='in') # performs OR filtering
246+
parent_ids = IntegerListAndFilter(field_name='parents__id') # performs AND filtering
247+
children_ids_or = IntegerListFilter(field_name='children', lookup_expr='in') # performs OR filtering
248+
children_ids = IntegerListAndFilter(field_name='children__id') # performs AND filtering
245249

246250
class Meta:
247251
model = Speaker
248-
fields = ["activeyn", "project_id"]
252+
fields = ["activeyn", "project_id", "parents", "children"]
249253

250254

251255
class TagFilterSet(django_filters.FilterSet):

roundware/api2/serializers.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,17 @@ def to_representation(self, obj):
342342

343343

344344
class SpeakerSerializer(serializers.ModelSerializer):
345+
children = serializers.SerializerMethodField()
346+
345347
class Meta:
346348
model = Speaker
347349
fields = "__all__"
348350

351+
def get_children(self, obj):
352+
# Access the reverse relationship via `children`
353+
return obj.children.values_list('id', flat=True) # Return IDs of children
354+
355+
349356
def to_representation(self, obj):
350357
result = super(SpeakerSerializer, self).to_representation(obj)
351358
result["project_id"] = result["project"]

roundware/api2/views.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,8 +1215,8 @@ class SpeakerViewSet(viewsets.ViewSet):
12151215
API V2: api/2/speakers/
12161216
api/2/speakers/:id/
12171217
"""
1218-
queryset = Speaker.objects.all()
1219-
permission_classes = (IsAuthenticated,)
1218+
queryset = Speaker.objects.prefetch_related('children', 'parents')
1219+
permission_classes = (IsAuthenticated, )
12201220

12211221
def get_object(self, pk):
12221222
try:

roundware/rw/admin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,14 +493,15 @@ class SpeakerAdmin(LeafletGeoAdmin, ProjectProtectedModelAdmin):
493493
list_display = ('id', 'activeyn', 'code', 'project', 'maxvolume', 'minvolume', 'shape', 'uri')
494494
list_filter = ('project', 'activeyn')
495495
list_editable = ('activeyn', 'maxvolume', 'minvolume', 'shape')
496+
filter_horizontal = ('parents', )
496497
ordering = ['id']
497498
save_as = True
498499
save_on_top = True
499500
map_width = "400px"
500501

501502
fieldsets = (
502503
(None, {
503-
'fields': ('activeyn', 'code', 'project', 'maxvolume', 'minvolume', 'uri', )
504+
'fields': ('activeyn', 'code', 'project', 'maxvolume', 'minvolume', 'uri', 'parents' )
504505
}),
505506
('Geographical Data', {
506507
'fields': ('shape', 'attenuation_distance'),
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 3.0 on 2024-11-16 12:30
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('rw', '0039_uiitem_filter_remove_validation'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='speaker',
15+
name='parents',
16+
field=models.ManyToManyField(blank=True, related_name='children', to='rw.Speaker'),
17+
),
18+
]

roundware/rw/models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,8 @@ def __init__(self, *args, **kwargs):
546546
attenuation_distance = models.IntegerField()
547547
attenuation_border = models.GeometryField(geography=True, null=True, editable=False)
548548

549+
parents = models.ManyToManyField('Speaker', related_name='children', symmetrical=False, blank=True)
550+
549551
objects = GeoManager()
550552

551553
def __str__(self):

roundware/rw/tests/test_models.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,19 @@ def test_get_flags(self):
107107

108108
def test_distance(self):
109109
distance = self.asset1.distance({'latitude': 0, 'longitude': 0})
110+
111+
class TestSpeaker(RWTestCase):
112+
113+
def setUp(self):
114+
super().setUp()
115+
116+
self.project = baker.make('rw.Project')
117+
self.speaker1 = baker.make('rw.Speaker', project=self.project)
118+
self.speaker2 = baker.make('rw.Speaker', project=self.project, parents=[self.speaker1])
119+
120+
def test_speaker_children(self):
121+
self.assertEqual(self.speaker1.parents.count(), 0)
122+
self.assertEqual(self.speaker2.parents.count(), 1)
123+
self.assertEqual(self.speaker1.children.count(), 1)
124+
self.assertEqual(self.speaker2.children.count(), 0)
125+

0 commit comments

Comments
 (0)