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

Resolve drf-yasg `ref_name` conflicts

This solves the problem of distinct serializers being confused because they have the same class name (e.g. `InterfaceSerializer`)

Fixes #2065.
Cristi Vîjdea 7 лет назад
Родитель
Сommit
3a62e9a322
2 измененных файлов с 22 добавлено и 2 удалено
  1. 21 1
      netbox/utilities/custom_inspectors.py
  2. 1 1
      requirements.txt

+ 21 - 1
netbox/utilities/custom_inspectors.py

@@ -1,14 +1,24 @@
 from drf_yasg import openapi
 from drf_yasg.inspectors import FieldInspector, NotHandled, PaginatorInspector, FilterInspector, SwaggerAutoSchema
+from drf_yasg.utils import get_serializer_ref_name
 from rest_framework.fields import ChoiceField
 from rest_framework.relations import ManyRelatedField
 from taggit_serializer.serializers import TagListSerializerField
 
+from dcim.api.serializers import InterfaceSerializer as DCIMInterfaceSerializer
+from virtualization.api.serializers import InterfaceSerializer as VirtualMachineInterfaceSerializer
 from extras.api.customfields import CustomFieldsSerializer
 from utilities.api import ChoiceField, SerializedPKRelatedField, WritableNestedSerializer
 
 
+# this might be ugly, but it limits drf_yasg-specific code to this file
+DCIMInterfaceSerializer.Meta.ref_name = 'DCIMInterface'
+VirtualMachineInterfaceSerializer.Meta.ref_name = 'VirtualMachineInterface'
+
+
 class NetBoxSwaggerAutoSchema(SwaggerAutoSchema):
+    writable_serializers = {}
+
     def get_request_serializer(self):
         serializer = super().get_request_serializer()
 
@@ -21,7 +31,17 @@ class NetBoxSwaggerAutoSchema(SwaggerAutoSchema):
                     properties[child_name] = None
 
             if properties:
-                writable_class = type('Writable' + type(serializer).__name__, (type(serializer),), properties)
+                if type(serializer) not in self.writable_serializers:
+                    writable_name = 'Writable' + type(serializer).__name__
+                    meta_class = getattr(type(serializer), 'Meta', None)
+                    if meta_class:
+                        ref_name = 'Writable' + get_serializer_ref_name(serializer)
+                        writable_meta = type('Meta', (meta_class,), {'ref_name': ref_name})
+                        properties['Meta'] = writable_meta
+
+                    self.writable_serializers[type(serializer)] = type(writable_name, (type(serializer),), properties)
+
+                writable_class = self.writable_serializers[type(serializer)]
                 serializer = writable_class()
 
         return serializer

+ 1 - 1
requirements.txt

@@ -8,7 +8,7 @@ django-taggit==0.23.0
 django-taggit-serializer==0.1.7
 django-timezone-field==3.0
 djangorestframework==3.9.0
-drf-yasg[validation]==1.11.1
+drf-yasg[validation]==1.14.0
 graphviz==0.10.1
 Markdown==2.6.11
 netaddr==0.7.19