We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`nautobot.core.api.serializers.WritableNestedSerializer` docstring is incorrect and confusing
<!--
    NOTE: This template is for use by maintainers only. Please do not submit
    an issue using this template unless you have been specifically asked to
    do so.
-->
### Proposed Changes
The docstring should read something like this:
> Returns a nested representation of an object on read, but accepts either the nested representation or just the PK value on write operations.

<!-- Provide justification for the proposed change(s). -->
### Justification
The current docstring is in conflict with the actual implementation by stating that only the PK value is supported on write, which is incorrect.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nautobot/core/api/serializers.py`
Content:
```
1 import uuid
2 
3 from django.core.exceptions import (
4     FieldError,
5     MultipleObjectsReturned,
6     ObjectDoesNotExist,
7 )
8 from django.db.models import AutoField, ManyToManyField
9 from drf_yasg.utils import swagger_serializer_method
10 from rest_framework import serializers
11 from rest_framework.exceptions import ValidationError
12 
13 from nautobot.utilities.utils import dict_to_filter_params
14 
15 
16 class BaseModelSerializer(serializers.ModelSerializer):
17     """
18     This base serializer implements common fields and logic for all ModelSerializers.
19     Namely it defines the `display` field which exposes a human friendly value for the given object.
20     """
21 
22     display = serializers.SerializerMethodField(read_only=True, help_text="Human friendly display value")
23 
24     @swagger_serializer_method(serializer_or_field=serializers.CharField)
25     def get_display(self, instance):
26         """
27         Return either the `display` property of the instance or `str(instance)`
28         """
29         return getattr(instance, "display", str(instance))
30 
31     def get_field_names(self, declared_fields, info):
32         """
33         Override get_field_names() to append the `display` field so it is always included in the
34         serializer's `Meta.fields`.
35 
36         DRF does not automatically add declared fields to `Meta.fields`, nor does it require that declared fields
37         on a super class be included in `Meta.fields` to allow for a subclass to include only a subset of declared
38         fields from the super. This means either we intercept and append the display field at this level, or
39         enforce by convention that all consumers of BaseModelSerializer include `display` in their `Meta.fields`
40         which would surely lead to errors of omission; therefore we have chosen the former approach.
41         """
42         fields = list(super().get_field_names(declared_fields, info))  # Meta.fields could be defined as a tuple
43         fields.append("display")
44 
45         return fields
46 
47 
48 class ValidatedModelSerializer(BaseModelSerializer):
49     """
50     Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during
51     validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
52     """
53 
54     def validate(self, data):
55 
56         # Remove custom fields data and tags (if any) prior to model validation
57         attrs = data.copy()
58         attrs.pop("custom_fields", None)
59         attrs.pop("tags", None)
60 
61         # Skip ManyToManyFields
62         for field in self.Meta.model._meta.get_fields():
63             if isinstance(field, ManyToManyField):
64                 attrs.pop(field.name, None)
65 
66         # Run clean() on an instance of the model
67         if self.instance is None:
68             instance = self.Meta.model(**attrs)
69         else:
70             instance = self.instance
71             for k, v in attrs.items():
72                 setattr(instance, k, v)
73         instance.full_clean()
74 
75         return data
76 
77 
78 class WritableNestedSerializer(BaseModelSerializer):
79     """
80     Returns a nested representation of an object on read, but accepts only a primary key on write.
81     """
82 
83     def to_internal_value(self, data):
84 
85         if data is None:
86             return None
87 
88         # Dictionary of related object attributes
89         if isinstance(data, dict):
90             params = dict_to_filter_params(data)
91             queryset = self.Meta.model.objects
92             try:
93                 return queryset.get(**params)
94             except ObjectDoesNotExist:
95                 raise ValidationError("Related object not found using the provided attributes: {}".format(params))
96             except MultipleObjectsReturned:
97                 raise ValidationError("Multiple objects match the provided attributes: {}".format(params))
98             except FieldError as e:
99                 raise ValidationError(e)
100 
101         queryset = self.Meta.model.objects
102         pk = None
103 
104         if isinstance(self.Meta.model._meta.pk, AutoField):
105             # PK is an int for this model. This is usually the User model
106             try:
107                 pk = int(data)
108             except (TypeError, ValueError):
109                 raise ValidationError(
110                     "Related objects must be referenced by ID or by dictionary of attributes. Received an "
111                     "unrecognized value: {}".format(data)
112                 )
113 
114         else:
115             # We assume a type of UUIDField for all other models
116 
117             # PK of related object
118             try:
119                 # Ensure the pk is a valid UUID
120                 pk = uuid.UUID(str(data))
121             except (TypeError, ValueError):
122                 raise ValidationError(
123                     "Related objects must be referenced by ID or by dictionary of attributes. Received an "
124                     "unrecognized value: {}".format(data)
125                 )
126 
127         try:
128             return queryset.get(pk=pk)
129         except ObjectDoesNotExist:
130             raise ValidationError("Related object not found using the provided ID: {}".format(pk))
131 
132 
133 class BulkOperationSerializer(serializers.Serializer):
134     id = serializers.CharField()  # This supports both UUIDs and numeric ID for the User model
135 
136 
137 #
138 # GraphQL, used by the openapi doc, not by the view
139 #
140 
141 
142 class GraphQLAPISerializer(serializers.Serializer):
143     query = serializers.CharField(required=True, help_text="GraphQL query")
144     variables = serializers.JSONField(required=False, help_text="Variables in JSON Format")
145
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/nautobot/core/api/serializers.py b/nautobot/core/api/serializers.py
--- a/nautobot/core/api/serializers.py
+++ b/nautobot/core/api/serializers.py
@@ -77,7 +77,8 @@
 
 class WritableNestedSerializer(BaseModelSerializer):
     """
-    Returns a nested representation of an object on read, but accepts only a primary key on write.
+    Returns a nested representation of an object on read, but accepts either the nested representation or the
+    primary key value on write operations.
     """
 
     def to_internal_value(self, data):

{"golden_diff": "diff --git a/nautobot/core/api/serializers.py b/nautobot/core/api/serializers.py\n--- a/nautobot/core/api/serializers.py\n+++ b/nautobot/core/api/serializers.py\n@@ -77,7 +77,8 @@\n \n class WritableNestedSerializer(BaseModelSerializer):\n     \"\"\"\n-    Returns a nested representation of an object on read, but accepts only a primary key on write.\n+    Returns a nested representation of an object on read, but accepts either the nested representation or the\n+    primary key value on write operations.\n     \"\"\"\n \n     def to_internal_value(self, data):\n", "issue": "`nautobot.core.api.serializers.WritableNestedSerializer` docstring is incorrect and confusing\n<!--\r\n    NOTE: This template is for use by maintainers only. Please do not submit\r\n    an issue using this template unless you have been specifically asked to\r\n    do so.\r\n-->\r\n### Proposed Changes\r\nThe docstring should read something like this:\r\n> Returns a nested representation of an object on read, but accepts either the nested representation or just the PK value on write operations.\r\n\r\n<!-- Provide justification for the proposed change(s). -->\r\n### Justification\r\nThe current docstring is in conflict with the actual implementation by stating that only the PK value is supported on write, which is incorrect.\n", "before_files": [{"content": "import uuid\n\nfrom django.core.exceptions import (\n    FieldError,\n    MultipleObjectsReturned,\n    ObjectDoesNotExist,\n)\nfrom django.db.models import AutoField, ManyToManyField\nfrom drf_yasg.utils import swagger_serializer_method\nfrom rest_framework import serializers\nfrom rest_framework.exceptions import ValidationError\n\nfrom nautobot.utilities.utils import dict_to_filter_params\n\n\nclass BaseModelSerializer(serializers.ModelSerializer):\n    \"\"\"\n    This base serializer implements common fields and logic for all ModelSerializers.\n    Namely it defines the `display` field which exposes a human friendly value for the given object.\n    \"\"\"\n\n    display = serializers.SerializerMethodField(read_only=True, help_text=\"Human friendly display value\")\n\n    @swagger_serializer_method(serializer_or_field=serializers.CharField)\n    def get_display(self, instance):\n        \"\"\"\n        Return either the `display` property of the instance or `str(instance)`\n        \"\"\"\n        return getattr(instance, \"display\", str(instance))\n\n    def get_field_names(self, declared_fields, info):\n        \"\"\"\n        Override get_field_names() to append the `display` field so it is always included in the\n        serializer's `Meta.fields`.\n\n        DRF does not automatically add declared fields to `Meta.fields`, nor does it require that declared fields\n        on a super class be included in `Meta.fields` to allow for a subclass to include only a subset of declared\n        fields from the super. This means either we intercept and append the display field at this level, or\n        enforce by convention that all consumers of BaseModelSerializer include `display` in their `Meta.fields`\n        which would surely lead to errors of omission; therefore we have chosen the former approach.\n        \"\"\"\n        fields = list(super().get_field_names(declared_fields, info))  # Meta.fields could be defined as a tuple\n        fields.append(\"display\")\n\n        return fields\n\n\nclass ValidatedModelSerializer(BaseModelSerializer):\n    \"\"\"\n    Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during\n    validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)\n    \"\"\"\n\n    def validate(self, data):\n\n        # Remove custom fields data and tags (if any) prior to model validation\n        attrs = data.copy()\n        attrs.pop(\"custom_fields\", None)\n        attrs.pop(\"tags\", None)\n\n        # Skip ManyToManyFields\n        for field in self.Meta.model._meta.get_fields():\n            if isinstance(field, ManyToManyField):\n                attrs.pop(field.name, None)\n\n        # Run clean() on an instance of the model\n        if self.instance is None:\n            instance = self.Meta.model(**attrs)\n        else:\n            instance = self.instance\n            for k, v in attrs.items():\n                setattr(instance, k, v)\n        instance.full_clean()\n\n        return data\n\n\nclass WritableNestedSerializer(BaseModelSerializer):\n    \"\"\"\n    Returns a nested representation of an object on read, but accepts only a primary key on write.\n    \"\"\"\n\n    def to_internal_value(self, data):\n\n        if data is None:\n            return None\n\n        # Dictionary of related object attributes\n        if isinstance(data, dict):\n            params = dict_to_filter_params(data)\n            queryset = self.Meta.model.objects\n            try:\n                return queryset.get(**params)\n            except ObjectDoesNotExist:\n                raise ValidationError(\"Related object not found using the provided attributes: {}\".format(params))\n            except MultipleObjectsReturned:\n                raise ValidationError(\"Multiple objects match the provided attributes: {}\".format(params))\n            except FieldError as e:\n                raise ValidationError(e)\n\n        queryset = self.Meta.model.objects\n        pk = None\n\n        if isinstance(self.Meta.model._meta.pk, AutoField):\n            # PK is an int for this model. This is usually the User model\n            try:\n                pk = int(data)\n            except (TypeError, ValueError):\n                raise ValidationError(\n                    \"Related objects must be referenced by ID or by dictionary of attributes. Received an \"\n                    \"unrecognized value: {}\".format(data)\n                )\n\n        else:\n            # We assume a type of UUIDField for all other models\n\n            # PK of related object\n            try:\n                # Ensure the pk is a valid UUID\n                pk = uuid.UUID(str(data))\n            except (TypeError, ValueError):\n                raise ValidationError(\n                    \"Related objects must be referenced by ID or by dictionary of attributes. Received an \"\n                    \"unrecognized value: {}\".format(data)\n                )\n\n        try:\n            return queryset.get(pk=pk)\n        except ObjectDoesNotExist:\n            raise ValidationError(\"Related object not found using the provided ID: {}\".format(pk))\n\n\nclass BulkOperationSerializer(serializers.Serializer):\n    id = serializers.CharField()  # This supports both UUIDs and numeric ID for the User model\n\n\n#\n# GraphQL, used by the openapi doc, not by the view\n#\n\n\nclass GraphQLAPISerializer(serializers.Serializer):\n    query = serializers.CharField(required=True, help_text=\"GraphQL query\")\n    variables = serializers.JSONField(required=False, help_text=\"Variables in JSON Format\")\n", "path": "nautobot/core/api/serializers.py"}], "after_files": [{"content": "import uuid\n\nfrom django.core.exceptions import (\n    FieldError,\n    MultipleObjectsReturned,\n    ObjectDoesNotExist,\n)\nfrom django.db.models import AutoField, ManyToManyField\nfrom drf_yasg.utils import swagger_serializer_method\nfrom rest_framework import serializers\nfrom rest_framework.exceptions import ValidationError\n\nfrom nautobot.utilities.utils import dict_to_filter_params\n\n\nclass BaseModelSerializer(serializers.ModelSerializer):\n    \"\"\"\n    This base serializer implements common fields and logic for all ModelSerializers.\n    Namely it defines the `display` field which exposes a human friendly value for the given object.\n    \"\"\"\n\n    display = serializers.SerializerMethodField(read_only=True, help_text=\"Human friendly display value\")\n\n    @swagger_serializer_method(serializer_or_field=serializers.CharField)\n    def get_display(self, instance):\n        \"\"\"\n        Return either the `display` property of the instance or `str(instance)`\n        \"\"\"\n        return getattr(instance, \"display\", str(instance))\n\n    def get_field_names(self, declared_fields, info):\n        \"\"\"\n        Override get_field_names() to append the `display` field so it is always included in the\n        serializer's `Meta.fields`.\n\n        DRF does not automatically add declared fields to `Meta.fields`, nor does it require that declared fields\n        on a super class be included in `Meta.fields` to allow for a subclass to include only a subset of declared\n        fields from the super. This means either we intercept and append the display field at this level, or\n        enforce by convention that all consumers of BaseModelSerializer include `display` in their `Meta.fields`\n        which would surely lead to errors of omission; therefore we have chosen the former approach.\n        \"\"\"\n        fields = list(super().get_field_names(declared_fields, info))  # Meta.fields could be defined as a tuple\n        fields.append(\"display\")\n\n        return fields\n\n\nclass ValidatedModelSerializer(BaseModelSerializer):\n    \"\"\"\n    Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during\n    validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)\n    \"\"\"\n\n    def validate(self, data):\n\n        # Remove custom fields data and tags (if any) prior to model validation\n        attrs = data.copy()\n        attrs.pop(\"custom_fields\", None)\n        attrs.pop(\"tags\", None)\n\n        # Skip ManyToManyFields\n        for field in self.Meta.model._meta.get_fields():\n            if isinstance(field, ManyToManyField):\n                attrs.pop(field.name, None)\n\n        # Run clean() on an instance of the model\n        if self.instance is None:\n            instance = self.Meta.model(**attrs)\n        else:\n            instance = self.instance\n            for k, v in attrs.items():\n                setattr(instance, k, v)\n        instance.full_clean()\n\n        return data\n\n\nclass WritableNestedSerializer(BaseModelSerializer):\n    \"\"\"\n    Returns a nested representation of an object on read, but accepts either the nested representation or the\n    primary key value on write operations.\n    \"\"\"\n\n    def to_internal_value(self, data):\n\n        if data is None:\n            return None\n\n        # Dictionary of related object attributes\n        if isinstance(data, dict):\n            params = dict_to_filter_params(data)\n            queryset = self.Meta.model.objects\n            try:\n                return queryset.get(**params)\n            except ObjectDoesNotExist:\n                raise ValidationError(\"Related object not found using the provided attributes: {}\".format(params))\n            except MultipleObjectsReturned:\n                raise ValidationError(\"Multiple objects match the provided attributes: {}\".format(params))\n            except FieldError as e:\n                raise ValidationError(e)\n\n        queryset = self.Meta.model.objects\n        pk = None\n\n        if isinstance(self.Meta.model._meta.pk, AutoField):\n            # PK is an int for this model. This is usually the User model\n            try:\n                pk = int(data)\n            except (TypeError, ValueError):\n                raise ValidationError(\n                    \"Related objects must be referenced by ID or by dictionary of attributes. Received an \"\n                    \"unrecognized value: {}\".format(data)\n                )\n\n        else:\n            # We assume a type of UUIDField for all other models\n\n            # PK of related object\n            try:\n                # Ensure the pk is a valid UUID\n                pk = uuid.UUID(str(data))\n            except (TypeError, ValueError):\n                raise ValidationError(\n                    \"Related objects must be referenced by ID or by dictionary of attributes. Received an \"\n                    \"unrecognized value: {}\".format(data)\n                )\n\n        try:\n            return queryset.get(pk=pk)\n        except ObjectDoesNotExist:\n            raise ValidationError(\"Related object not found using the provided ID: {}\".format(pk))\n\n\nclass BulkOperationSerializer(serializers.Serializer):\n    id = serializers.CharField()  # This supports both UUIDs and numeric ID for the User model\n\n\n#\n# GraphQL, used by the openapi doc, not by the view\n#\n\n\nclass GraphQLAPISerializer(serializers.Serializer):\n    query = serializers.CharField(required=True, help_text=\"GraphQL query\")\n    variables = serializers.JSONField(required=False, help_text=\"Variables in JSON Format\")\n", "path": "nautobot/core/api/serializers.py"}]}