Repository: netbox-community/netbox

Issue:
API Docs - Typo error on /virtualisation/interfaces/
<!--
    Before opening a new issue, please search through the existing issues to
    see if your topic has already been addressed. Note that you may need to
    remove the "is:open" filter from the search bar to include closed issues.

    Check the appropriate type for your issue below by placing an x between the
    brackets. For assistance with installation issues, or for any other issues
    other than those listed below, please raise your topic for discussion on
    our mailing list:

        https://groups.google.com/forum/#!forum/netbox-discuss

    Please note that issues which do not fall under any of the below categories
    will be closed. Due to an excessive backlog of feature requests, we are
    not currently accepting any proposals which extend NetBox's feature scope.

    Do not prepend any sort of tag to your issue's title. An administrator will
    review your issue and assign labels as appropriate.
--->
### Issue type
[ ] Feature request <!-- An enhancement of existing functionality -->
[ ] Bug report      <!-- Unexpected or erroneous behavior -->
[X] Documentation   <!-- A modification to the documentation -->

<!--
    Please describe the environment in which you are running NetBox. (Be sure
    to verify that you are running the latest stable release of NetBox before
    submitting a bug report.) If you are submitting a bug report and have made
    any changes to the code base, please first validate that your bug can be
    recreated while running an official release.
-->
### Environment
* Python version:  3.6.5
* NetBox version:  2.3.3

<!--
    BUG REPORTS must include:
        * A list of the steps needed for someone else to reproduce the bug
        * A description of the expected and observed behavior
        * Any relevant error messages (screenshots may also help)

    FEATURE REQUESTS must include:
        * A detailed description of the proposed functionality
        * A use case for the new feature
        * A rough description of any necessary changes to the database schema
        * Any relevant third-party libraries which would be needed
-->
### Description
Hello,

On the API documentation it seems there is a little error.

On `/virtualisation/interfaces/` endpoint, method `POST`, the field `device` is marked as mandatory, but the API only respond to the field `virtual_machine`.

The error message returned by the API is also misleading :
```
{
 "non_field_errors": [
   "An interface must belong to either a device or a virtual machine."
 ]
}
```

It seems the error is also present on `/virtualisation/interfaces/{id}` methods `PUT` and `PATCH`.


Discussion:
I resolved my problem by this report.
thank you so much.

I hope to modified documentation.
My guess is drf-yasg is caching the serializer definition internally by name. Devices and virtual machines each use a unique serializer for interfaces, however both are named `InterfaceSerializer`.
This will be covered in #2665 

Resolving patch:
diff --git a/netbox/utilities/custom_inspectors.py b/netbox/utilities/custom_inspectors.py
--- a/netbox/utilities/custom_inspectors.py
+++ b/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 @@ def get_request_serializer(self):
                     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


Test patch: