Skip to content

Commit 9c1d661

Browse files
committed
graphQL with has_path_data and has_type_specific_data filtering
1 parent e3deb47 commit 9c1d661

File tree

2 files changed

+21
-56
lines changed

2 files changed

+21
-56
lines changed

cesnet_service_path_plugin/graphql/filters.py

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -98,27 +98,28 @@ class SegmentFilter(NetBoxModelFilterMixin):
9898
strawberry_django.filter_field()
9999
)
100100

101-
# Custom filter for checking if segment has path data
102-
has_path_data: Optional[bool] = None
103-
104-
# Custom filter for checking if segment has type-specific data
105-
has_type_specific_data: Optional[bool] = None
106-
107-
def filter_has_path_data(self, queryset, info):
108-
if self.has_path_data is None:
109-
return queryset
110-
if self.has_path_data:
111-
return queryset.filter(path_geometry__isnull=False)
101+
# Custom filter methods with decorator approach
102+
@strawberry_django.filter_field
103+
def has_path_data(self, value: bool, prefix: str) -> Q:
104+
"""Filter segments based on whether they have path geometry data"""
105+
106+
if value:
107+
# Filter for segments WITH path data
108+
return Q(**{f"{prefix}path_geometry__isnull": False})
112109
else:
113-
return queryset.filter(path_geometry__isnull=True)
114-
115-
def filter_has_type_specific_data(self, queryset, info):
116-
if self.has_type_specific_data is None:
117-
return queryset
118-
if self.has_type_specific_data:
119-
return queryset.exclude(type_specific_data={})
110+
# Filter for segments WITHOUT path data
111+
return Q(**{f"{prefix}path_geometry__isnull": True})
112+
113+
@strawberry_django.filter_field
114+
def has_type_specific_data(self, value: bool, prefix: str) -> Q:
115+
"""Filter segments based on whether they have type-specific data"""
116+
if value:
117+
# Has type-specific data: JSON field is not empty and not null
118+
# Return Q object that excludes empty dict and null values
119+
return ~Q(**{f"{prefix}type_specific_data": {}}) & ~Q(**{f"{prefix}type_specific_data__isnull": True})
120120
else:
121-
return queryset.filter(type_specific_data={})
121+
# No type-specific data: JSON field is empty or null
122+
return Q(**{f"{prefix}type_specific_data": {}}) | Q(**{f"{prefix}type_specific_data__isnull": True})
122123

123124

124125
@strawberry_django.filter(ServicePath, lookups=True)

cesnet_service_path_plugin/graphql/types.py

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
from typing import Annotated, List, Optional
2-
import logging
2+
33
from circuits.graphql.types import CircuitType, ProviderType
44
from dcim.graphql.types import LocationType, SiteType
55
from netbox.graphql.types import NetBoxObjectType
66
from strawberry import auto, lazy, field
77
from strawberry_django import type as strawberry_django_type
88
import strawberry
99

10-
1110
from cesnet_service_path_plugin.models import (
1211
Segment,
1312
SegmentCircuitMapping,
@@ -24,9 +23,6 @@
2423
)
2524

2625

27-
logger = logging.getLogger(__name__)
28-
29-
3026
# Custom scalar types for path geometry data
3127
@strawberry.type
3228
class PathBounds:
@@ -74,8 +70,6 @@ def has_type_specific_data(self) -> bool:
7470
"""Whether this segment has type-specific data"""
7571
if hasattr(self, "has_type_specific_data"):
7672
return self.has_type_specific_data()
77-
logger.warning("Segment has no type-specific data")
78-
logger.debug(f"Type-specific data: {self.type_specific_data}")
7973
return bool(self.type_specific_data)
8074

8175
@field
@@ -92,22 +86,6 @@ def segment_type_display(self) -> Optional[str]:
9286
return self.get_segment_type_display()
9387
return None
9488

95-
@field
96-
def type_specific_schema(self) -> Optional[strawberry.scalars.JSON]:
97-
"""Schema for the segment's type"""
98-
from cesnet_service_path_plugin.models.segment_types import SEGMENT_TYPE_SCHEMAS
99-
100-
if self.segment_type:
101-
return SEGMENT_TYPE_SCHEMAS.get(self.segment_type, {})
102-
return None
103-
104-
@field
105-
def has_type_specific_data(self) -> bool:
106-
"""Whether this segment has type-specific data"""
107-
if hasattr(self, "has_type_specific_data"):
108-
return self.has_type_specific_data()
109-
return bool(self.type_specific_data)
110-
11189
@field
11290
def path_geometry_geojson(self) -> Optional[strawberry.scalars.JSON]:
11391
"""Path geometry as GeoJSON Feature"""
@@ -155,20 +133,6 @@ def path_bounds(self) -> Optional[PathBounds]:
155133
return PathBounds(xmin=bounds[0], ymin=bounds[1], xmax=bounds[2], ymax=bounds[3])
156134
return None
157135

158-
@field
159-
def path_segment_count(self) -> int:
160-
"""Number of path segments in the MultiLineString"""
161-
if hasattr(self, "get_path_segment_count"):
162-
return self.get_path_segment_count()
163-
return 0
164-
165-
@field
166-
def path_total_points(self) -> int:
167-
"""Total number of coordinate points across all segments"""
168-
if hasattr(self, "get_total_points"):
169-
return self.get_total_points()
170-
return 0
171-
172136

173137
@strawberry_django_type(SegmentCircuitMapping, filters=SegmentCircuitMappingFilter)
174138
class SegmentCircuitMappingType(NetBoxObjectType):

0 commit comments

Comments
 (0)