prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  OPTIONS returns all Status choices instead of ones only related to the specific model
  <!--
      NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED.
  
      This form is only for reporting reproducible bugs. If you need assistance
      with Nautobot installation, or if you have a general question, please start a
      discussion instead: https://github.com/nautobot/nautobot/discussions
  
      Please describe the environment in which you are running Nautobot. Be sure
      that you are running an unmodified instance of the latest stable release
      before submitting a bug report, and that any plugins have been disabled.
  -->
  ### Environment
  * Python version: 3.8
  * Nautobot version: 1.0.1
  
  <!--
      Describe in detail the exact steps that someone else can take to reproduce
      this bug using the current stable release of Nautobot. Begin with the
      creation of any necessary database objects and call out every operation
      being performed explicitly. If reporting a bug in the REST API, be sure to
      reconstruct the raw HTTP request(s) being made: Don't rely on a client
      library such as pynautobot.
  -->
  ### Steps to Reproduce
  Cables should only have three status choices and virtual machines should have 6. Numbers are arbitrary, but this is with a fresh install of Nautobot.
  
  ```python
  >>> nb.dcim.cables.choices()['status']
  [{'value': 'active', 'display': 'Active'}, {'value': 'available', 'display': 'Available'}, {'value': 'connected', 'display': 'Connected'}, {'value': 'container', 'display': 'Container'}, {'value': 'decommissioned', 'display': 'Decommissioned'}, {'value': 'decommissioning', 'display': 'Decommissioning'}, {'value': 'deprecated', 'display': 'Deprecated'}, {'value': 'deprovisioning', 'display': 'Deprovisioning'}, {'value': 'dhcp', 'display': 'DHCP'}, {'value': 'failed', 'display': 'Failed'}, {'value': 'inventory', 'display': 'Inventory'}, {'value': 'offline', 'display': 'Offline'}, {'value': 'planned', 'display': 'Planned'}, {'value': 'provisioning', 'display': 'Provisioning'}, {'value': 'reserved', 'display': 'Reserved'}, {'value': 'retired', 'display': 'Retired'}, {'value': 'slaac', 'display': 'SLAAC'}, {'value': 'staged', 'display': 'Staged'}, {'value': 'staging', 'display': 'Staging'}]
  >>> nb.virtualization.virtual_machines.choices()['status']
  [{'value': 'active', 'display': 'Active'}, {'value': 'available', 'display': 'Available'}, {'value': 'connected', 'display': 'Connected'}, {'value': 'container', 'display': 'Container'}, {'value': 'decommissioned', 'display': 'Decommissioned'}, {'value': 'decommissioning', 'display': 'Decommissioning'}, {'value': 'deprecated', 'display': 'Deprecated'}, {'value': 'deprovisioning', 'display': 'Deprovisioning'}, {'value': 'dhcp', 'display': 'DHCP'}, {'value': 'failed', 'display': 'Failed'}, {'value': 'inventory', 'display': 'Inventory'}, {'value': 'offline', 'display': 'Offline'}, {'value': 'planned', 'display': 'Planned'}, {'value': 'provisioning', 'display': 'Provisioning'}, {'value': 'reserved', 'display': 'Reserved'}, {'value': 'retired', 'display': 'Retired'}, {'value': 'slaac', 'display': 'SLAAC'}, {'value': 'staged', 'display': 'Staged'}, {'value': 'staging', 'display': 'Staging'}]
  ```
  
  I haven't been able to dig into it too much, but I believe this is the culprit.
  
  https://github.com/nautobot/nautobot/blob/develop/nautobot/extras/api/serializers.py#L621
  
  <!-- What did you expect to happen? -->
  ### Expected Behavior
  
  ```python
  >>> nb.dcim.cables.choices()['status']
  [{'value': 'connected', 'display': 'Connected'}, {'value': 'decommissioning', 'display': 'Decommissioning'}, {'value': 'planned', 'display': 'Planned'}]
  >>> nb.virtualization.virtual_machines.choices()['status']
  [{'value': 'active', 'display': 'Active'}, {'value': 'decommissioning', 'display': 'Decommissioning'}, {'value': 'failed', 'display': 'Failed'}, {'value': 'offline', 'display': 'Offline'}, {'value': 'planned', 'display': 'Planned'}, {'value': 'staged', 'display': 'Staged'}]
  ```
  
  <!-- What happened instead? -->
  ### Observed Behavior
  See **Steps to Reproduce**.
  
  --- 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/extras/api/fields.py`
  Content:
  ```
  1 from collections import OrderedDict
  2 
  3 from rest_framework import serializers
  4 
  5 
  6 class MultipleChoiceJSONField(serializers.MultipleChoiceField):
  7     """A MultipleChoiceField that renders the received value as a JSON-compatible list rather than a set."""
  8 
  9     def to_internal_value(self, data):
  10         set_value = super().to_internal_value(data)
  11         return sorted(set_value)
  12 
  13 
  14 class StatusSerializerField(serializers.SlugRelatedField):
  15     """Serializer field for `Status` object fields."""
  16 
  17     show_choices = True
  18 
  19     def __init__(self, **kwargs):
  20         kwargs.setdefault("slug_field", "slug")
  21         super().__init__(**kwargs)
  22 
  23     def to_representation(self, obj):
  24         """Make this field compatible w/ the existing API for `ChoiceField`."""
  25         if obj == "":
  26             return None
  27 
  28         return OrderedDict(
  29             [
  30                 ("value", obj.slug),
  31                 ("label", str(obj)),
  32             ]
  33         )
  34 
  35     def to_internal_value(self, data):
  36         """Always lower-case the custom choice value."""
  37         if hasattr(data, "lower"):
  38             data = data.lower()
  39         return super().to_internal_value(data)
  40 
  41     def get_choices(self, cutoff=None):
  42         """
  43         Return a nested list of dicts for enum choices.
  44 
  45         This had to be overloaded since the base method calls
  46         `to_representation()` which in our case is an OrderedDict and can't be
  47         nested.
  48         """
  49         queryset = self.get_queryset()
  50         if queryset is None:
  51             # Ensure that field.choices returns something sensible
  52             # even when accessed with a read-only field.
  53             return {}
  54 
  55         if cutoff is not None:
  56             queryset = queryset[:cutoff]
  57 
  58         return OrderedDict([(item.slug, self.display_value(item)) for item in queryset])
  59
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/nautobot/extras/api/fields.py b/nautobot/extras/api/fields.py
  --- a/nautobot/extras/api/fields.py
  +++ b/nautobot/extras/api/fields.py
  @@ -38,6 +38,12 @@
               data = data.lower()
           return super().to_internal_value(data)
   
  +    def get_queryset(self):
  +        """Only emit status options for this model/field combination."""
  +        queryset = super().get_queryset()
  +        model = self.parent.Meta.model
  +        return queryset.get_for_model(model)
  +
       def get_choices(self, cutoff=None):
           """
           Return a nested list of dicts for enum choices.
  
verification_info: {"golden_diff": "diff --git a/nautobot/extras/api/fields.py b/nautobot/extras/api/fields.py\n--- a/nautobot/extras/api/fields.py\n+++ b/nautobot/extras/api/fields.py\n@@ -38,6 +38,12 @@\n             data = data.lower()\n         return super().to_internal_value(data)\n \n+    def get_queryset(self):\n+        \"\"\"Only emit status options for this model/field combination.\"\"\"\n+        queryset = super().get_queryset()\n+        model = self.parent.Meta.model\n+        return queryset.get_for_model(model)\n+\n     def get_choices(self, cutoff=None):\n         \"\"\"\n         Return a nested list of dicts for enum choices.\n", "issue": "OPTIONS returns all Status choices instead of ones only related to the specific model\n<!--\r\n    NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED.\r\n\r\n    This form is only for reporting reproducible bugs. If you need assistance\r\n    with Nautobot installation, or if you have a general question, please start a\r\n    discussion instead: https://github.com/nautobot/nautobot/discussions\r\n\r\n    Please describe the environment in which you are running Nautobot. Be sure\r\n    that you are running an unmodified instance of the latest stable release\r\n    before submitting a bug report, and that any plugins have been disabled.\r\n-->\r\n### Environment\r\n* Python version: 3.8\r\n* Nautobot version: 1.0.1\r\n\r\n<!--\r\n    Describe in detail the exact steps that someone else can take to reproduce\r\n    this bug using the current stable release of Nautobot. Begin with the\r\n    creation of any necessary database objects and call out every operation\r\n    being performed explicitly. If reporting a bug in the REST API, be sure to\r\n    reconstruct the raw HTTP request(s) being made: Don't rely on a client\r\n    library such as pynautobot.\r\n-->\r\n### Steps to Reproduce\r\nCables should only have three status choices and virtual machines should have 6. Numbers are arbitrary, but this is with a fresh install of Nautobot.\r\n\r\n```python\r\n>>> nb.dcim.cables.choices()['status']\r\n[{'value': 'active', 'display': 'Active'}, {'value': 'available', 'display': 'Available'}, {'value': 'connected', 'display': 'Connected'}, {'value': 'container', 'display': 'Container'}, {'value': 'decommissioned', 'display': 'Decommissioned'}, {'value': 'decommissioning', 'display': 'Decommissioning'}, {'value': 'deprecated', 'display': 'Deprecated'}, {'value': 'deprovisioning', 'display': 'Deprovisioning'}, {'value': 'dhcp', 'display': 'DHCP'}, {'value': 'failed', 'display': 'Failed'}, {'value': 'inventory', 'display': 'Inventory'}, {'value': 'offline', 'display': 'Offline'}, {'value': 'planned', 'display': 'Planned'}, {'value': 'provisioning', 'display': 'Provisioning'}, {'value': 'reserved', 'display': 'Reserved'}, {'value': 'retired', 'display': 'Retired'}, {'value': 'slaac', 'display': 'SLAAC'}, {'value': 'staged', 'display': 'Staged'}, {'value': 'staging', 'display': 'Staging'}]\r\n>>> nb.virtualization.virtual_machines.choices()['status']\r\n[{'value': 'active', 'display': 'Active'}, {'value': 'available', 'display': 'Available'}, {'value': 'connected', 'display': 'Connected'}, {'value': 'container', 'display': 'Container'}, {'value': 'decommissioned', 'display': 'Decommissioned'}, {'value': 'decommissioning', 'display': 'Decommissioning'}, {'value': 'deprecated', 'display': 'Deprecated'}, {'value': 'deprovisioning', 'display': 'Deprovisioning'}, {'value': 'dhcp', 'display': 'DHCP'}, {'value': 'failed', 'display': 'Failed'}, {'value': 'inventory', 'display': 'Inventory'}, {'value': 'offline', 'display': 'Offline'}, {'value': 'planned', 'display': 'Planned'}, {'value': 'provisioning', 'display': 'Provisioning'}, {'value': 'reserved', 'display': 'Reserved'}, {'value': 'retired', 'display': 'Retired'}, {'value': 'slaac', 'display': 'SLAAC'}, {'value': 'staged', 'display': 'Staged'}, {'value': 'staging', 'display': 'Staging'}]\r\n```\r\n\r\nI haven't been able to dig into it too much, but I believe this is the culprit.\r\n\r\nhttps://github.com/nautobot/nautobot/blob/develop/nautobot/extras/api/serializers.py#L621\r\n\r\n<!-- What did you expect to happen? -->\r\n### Expected Behavior\r\n\r\n```python\r\n>>> nb.dcim.cables.choices()['status']\r\n[{'value': 'connected', 'display': 'Connected'}, {'value': 'decommissioning', 'display': 'Decommissioning'}, {'value': 'planned', 'display': 'Planned'}]\r\n>>> nb.virtualization.virtual_machines.choices()['status']\r\n[{'value': 'active', 'display': 'Active'}, {'value': 'decommissioning', 'display': 'Decommissioning'}, {'value': 'failed', 'display': 'Failed'}, {'value': 'offline', 'display': 'Offline'}, {'value': 'planned', 'display': 'Planned'}, {'value': 'staged', 'display': 'Staged'}]\r\n```\r\n\r\n<!-- What happened instead? -->\r\n### Observed Behavior\r\nSee **Steps to Reproduce**.\n", "before_files": [{"content": "from collections import OrderedDict\n\nfrom rest_framework import serializers\n\n\nclass MultipleChoiceJSONField(serializers.MultipleChoiceField):\n    \"\"\"A MultipleChoiceField that renders the received value as a JSON-compatible list rather than a set.\"\"\"\n\n    def to_internal_value(self, data):\n        set_value = super().to_internal_value(data)\n        return sorted(set_value)\n\n\nclass StatusSerializerField(serializers.SlugRelatedField):\n    \"\"\"Serializer field for `Status` object fields.\"\"\"\n\n    show_choices = True\n\n    def __init__(self, **kwargs):\n        kwargs.setdefault(\"slug_field\", \"slug\")\n        super().__init__(**kwargs)\n\n    def to_representation(self, obj):\n        \"\"\"Make this field compatible w/ the existing API for `ChoiceField`.\"\"\"\n        if obj == \"\":\n            return None\n\n        return OrderedDict(\n            [\n                (\"value\", obj.slug),\n                (\"label\", str(obj)),\n            ]\n        )\n\n    def to_internal_value(self, data):\n        \"\"\"Always lower-case the custom choice value.\"\"\"\n        if hasattr(data, \"lower\"):\n            data = data.lower()\n        return super().to_internal_value(data)\n\n    def get_choices(self, cutoff=None):\n        \"\"\"\n        Return a nested list of dicts for enum choices.\n\n        This had to be overloaded since the base method calls\n        `to_representation()` which in our case is an OrderedDict and can't be\n        nested.\n        \"\"\"\n        queryset = self.get_queryset()\n        if queryset is None:\n            # Ensure that field.choices returns something sensible\n            # even when accessed with a read-only field.\n            return {}\n\n        if cutoff is not None:\n            queryset = queryset[:cutoff]\n\n        return OrderedDict([(item.slug, self.display_value(item)) for item in queryset])\n", "path": "nautobot/extras/api/fields.py"}], "after_files": [{"content": "from collections import OrderedDict\n\nfrom rest_framework import serializers\n\n\nclass MultipleChoiceJSONField(serializers.MultipleChoiceField):\n    \"\"\"A MultipleChoiceField that renders the received value as a JSON-compatible list rather than a set.\"\"\"\n\n    def to_internal_value(self, data):\n        set_value = super().to_internal_value(data)\n        return sorted(set_value)\n\n\nclass StatusSerializerField(serializers.SlugRelatedField):\n    \"\"\"Serializer field for `Status` object fields.\"\"\"\n\n    show_choices = True\n\n    def __init__(self, **kwargs):\n        kwargs.setdefault(\"slug_field\", \"slug\")\n        super().__init__(**kwargs)\n\n    def to_representation(self, obj):\n        \"\"\"Make this field compatible w/ the existing API for `ChoiceField`.\"\"\"\n        if obj == \"\":\n            return None\n\n        return OrderedDict(\n            [\n                (\"value\", obj.slug),\n                (\"label\", str(obj)),\n            ]\n        )\n\n    def to_internal_value(self, data):\n        \"\"\"Always lower-case the custom choice value.\"\"\"\n        if hasattr(data, \"lower\"):\n            data = data.lower()\n        return super().to_internal_value(data)\n\n    def get_queryset(self):\n        \"\"\"Only emit status options for this model/field combination.\"\"\"\n        queryset = super().get_queryset()\n        model = self.parent.Meta.model\n        return queryset.get_for_model(model)\n\n    def get_choices(self, cutoff=None):\n        \"\"\"\n        Return a nested list of dicts for enum choices.\n\n        This had to be overloaded since the base method calls\n        `to_representation()` which in our case is an OrderedDict and can't be\n        nested.\n        \"\"\"\n        queryset = self.get_queryset()\n        if queryset is None:\n            # Ensure that field.choices returns something sensible\n            # even when accessed with a read-only field.\n            return {}\n\n        if cutoff is not None:\n            queryset = queryset[:cutoff]\n\n        return OrderedDict([(item.slug, self.display_value(item)) for item in queryset])\n", "path": "nautobot/extras/api/fields.py"}]}