Просмотр исходного кода

9856 working auto filter generation

Arthur 1 год назад
Родитель
Сommit
fe3f2c8958
1 измененных файлов с 175 добавлено и 3 удалено
  1. 175 3
      netbox/circuits/graphql/filters.py

+ 175 - 3
netbox/circuits/graphql/filters.py

@@ -1,11 +1,14 @@
 from typing import List
 
+import django_filters
 import strawberry
 import strawberry_django
 from circuits import filtersets, models
+from functools import partial, partialmethod, wraps
 from strawberry import auto
 from strawberry_django.filters import FilterLookup
 from tenancy.graphql.filter_mixins import ContactModelFilterMixin, TenancyFilterMixin
+from utilities.filters import *
 
 from netbox.graphql.filter_mixins import NetBoxModelFilterMixin
 
@@ -18,6 +21,167 @@ __all__ = (
     'ProviderNetworkFilter',
 )
 
+# def filter_by_filterset(self, queryset, key, cls, filterset):
+#     breakpoint()
+#     return filterset(data={key: getattr(cls, key)}, queryset=queryset).qs
+
+
+def autotype_decorator(filterset):
+
+    def wrapper(cls):
+        cls.filterset = filterset
+        fields = filterset.get_fields()
+        print(f"fields: {fields}")
+        for fieldname in fields.keys():
+            if fieldname not in cls.__annotations__:
+                cls.__annotations__[fieldname] = auto
+
+        # fields = list(filterset.get_fields().keys())
+        declared_filters = filterset.declared_filters
+        print(f"declared_filters: {declared_filters}")
+        print("")
+        for fieldname, v in declared_filters.items():
+            create_function = False
+            attr_type = None
+            print(f"{fieldname}: {v}")
+
+            if isinstance(v, ContentTypeFilter):
+                print("ContentTypeFilter")
+            elif isinstance(v, MACAddressFilter):
+                print("MACAddressFilter")
+            elif isinstance(v, MultiValueArrayFilter):
+                print("MultiValueArrayFilter")
+            elif isinstance(v, MultiValueCharFilter):
+                print("MultiValueCharFilter")
+            elif isinstance(v, MultiValueDateFilter):
+                print("MultiValueDateFilter")
+            elif isinstance(v, MultiValueDateTimeFilter):
+                print("MultiValueDateTimeFilter")
+            elif isinstance(v, MultiValueDecimalFilter):
+                print("MultiValueDecimalFilter")
+            elif isinstance(v, MultiValueMACAddressFilter):
+                print("MultiValueMACAddressFilter")
+            elif isinstance(v, MultiValueNumberFilter):
+                print("MultiValueNumberFilter")
+            elif isinstance(v, MultiValueTimeFilter):
+                print("MultiValueTimeFilter")
+            elif isinstance(v, MultiValueWWNFilter):
+                print("MultiValueWWNFilter")
+            elif isinstance(v, NullableCharFieldFilter):
+                print("NullableCharFieldFilter")
+            elif isinstance(v, NumericArrayFilter):
+                print("NumericArrayFilter")
+            elif isinstance(v, TreeNodeMultipleChoiceFilter):
+                print("TreeNodeMultipleChoiceFilter")
+
+            elif issubclass(type(v), django_filters.CharFilter):
+                print("CharFilter")
+            elif issubclass(type(v), django_filters.UUIDFilter):
+                print("UUIDFilter")
+            elif issubclass(type(v), django_filters.BooleanFilter):
+                print("BooleanFilter")
+            elif issubclass(type(v), django_filters.ChoiceFilter):
+                print("ChoiceFilter")
+            elif issubclass(type(v), django_filters.TypedChoiceFilter):
+                print("TypedChoiceFilter")
+            elif issubclass(type(v), django_filters.DateFilter):
+                print("DateFilter")
+            elif issubclass(type(v), django_filters.TimeFilter):
+                print("TimeFilter")
+            elif issubclass(type(v), django_filters.DateTimeFilter):
+                print("DateTimeFilter")
+            elif issubclass(type(v), django_filters.IsoDateTimeFilter):
+                print("IsoDateTimeFilter")
+            elif issubclass(type(v), django_filters.DurationFilter):
+                print("DurationFilter")
+            elif issubclass(type(v), django_filters.ModelChoiceFilter):
+                print("ModelChoiceFilter")
+            elif issubclass(type(v), django_filters.ModelMultipleChoiceFilter):
+                create_function = True
+                attr_type = List[str] | None
+                print("ModelMultipleChoiceFilter")
+            elif issubclass(type(v), django_filters.NumberFilter):
+                print("NumberFilter")
+            elif issubclass(type(v), django_filters.NumericRangeFilter):
+                print("NumericRangeFilter")
+            elif issubclass(type(v), django_filters.RangeFilter):
+                print("RangeFilter")
+            elif issubclass(type(v), django_filters.DateRangeFilter):
+                print("DateRangeFilter")
+            elif issubclass(type(v), django_filters.DateFromToRangeFilter):
+                print("DateFromToRangeFilter")
+            elif issubclass(type(v), django_filters.DateTimeFromToRangeFilter):
+                print("DateTimeFromToRangeFilter")
+            elif issubclass(type(v), django_filters.IsoDateTimeFromToRangeFilter):
+                print("IsoDateTimeFromToRangeFilter")
+            elif issubclass(type(v), django_filters.TimeRangeFilter):
+                print("TimeRangeFilter")
+            elif issubclass(type(v), django_filters.AllValuesFilter):
+                print("AllValuesFilter")
+            elif issubclass(type(v), django_filters.AllValuesMultipleFilter):
+                print("AllValuesMultipleFilter")
+            elif issubclass(type(v), django_filters.LookupChoiceFilter):
+                print("LookupChoiceFilter")
+            elif issubclass(type(v), django_filters.BaseInFilter):
+                print("BaseInFilter")
+            elif issubclass(type(v), django_filters.BaseRangeFilter):
+                print("BaseRangeFilter")
+            elif issubclass(type(v), django_filters.OrderingFilter):
+                print("OrderingFilter")
+            elif issubclass(type(v), django_filters.TypedMultipleChoiceFilter):
+                print("TypedMultipleChoiceFilter")
+            elif issubclass(type(v), django_filters.MultipleChoiceFilter):
+                print("MultipleChoiceFilter")
+            else:
+                print("unknown type!")
+
+            if fieldname not in cls.__annotations__ and attr_type:
+                print(f"adding {fieldname} to class")
+                cls.__annotations__[fieldname] = attr_type
+
+            fname = f"filter_{fieldname}"
+            if create_function and not hasattr(cls, fname):
+                print(f"creating function {fname}")
+                filter_by_filterset = getattr(cls, 'filter_by_filterset')
+                setattr(cls, fname, partialmethod(filter_by_filterset, key=fieldname))
+                # setattr(cls, fname, partial(filter_by_filterset, key=fieldname, cls=cls, filterset=filterset))
+
+        print("")
+        return cls
+
+    return wrapper
+
+
+"""
+class autotype_decorator(object):
+    def __init__(self, filterset):
+        self.filterset = filterset
+    def __call__(self, cls):
+        class Wrapped(cls):
+            '''
+            cls.filterset = filterset
+            fields = filterset.get_fields()
+            print(fields)
+            fields = list(filterset.get_fields().keys())
+            declared_filters = filterset.declared_filters
+            print(declared_filters)
+            fields.extend(list(filterset.declared_filters.keys()))
+            for field in fields:
+                print(field)
+
+            '''
+            print(f"cls: {cls}")
+            print(f"self: {self}")
+            vars()['cid'] = strawberry.unset.UnsetType
+            # setattr(cls, 'cid', strawberry.unset.UnsetType)
+            pass
+
+        setattr(Wrapped, 'cid', strawberry.unset.UnsetType)
+        print(f"hasattr: {hasattr(Wrapped, 'cid')}")
+        print(Wrapped)
+        return Wrapped
+"""
+
 
 @strawberry_django.filter(models.CircuitTermination, lookups=True)
 class CircuitTerminationFilter(filtersets.CircuitTerminationFilterSet):
@@ -36,10 +200,17 @@ class CircuitTerminationFilter(filtersets.CircuitTerminationFilterSet):
 
 
 @strawberry_django.filter(models.Circuit, lookups=True)
-class CircuitFilter(NetBoxModelFilterMixin, TenancyFilterMixin, ContactModelFilterMixin):
-    filterset = filtersets.CircuitFilterSet
+@autotype_decorator(filtersets.CircuitFilterSet)
+class CircuitFilter:
+    # class CircuitFilter(NetBoxModelFilterMixin, TenancyFilterMixin, ContactModelFilterMixin):
+
+    def filter_by_filterset(self, queryset, key):
+        return self.filterset(data={key: getattr(self, key)}, queryset=queryset).qs
 
-    cid: auto
+    pass
+    """
+    # vars()['cid'] = strawberry.unset.UnsetType
+    # cid: auto
     description: auto
     install_date: auto
     termination_date: auto
@@ -94,6 +265,7 @@ class CircuitFilter(NetBoxModelFilterMixin, TenancyFilterMixin, ContactModelFilt
 
     def filter_site(self, queryset):
         return self.filter_by_filterset(queryset, 'site')
+    """
 
 
 # @strawberry_django.filter(models.Circuit, lookups=True)