prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Add Contacts field to Virtual Machines table view
  ### NetBox version
  
  v3.2.7
  
  ### Feature type
  
  Change to existing functionality
  
  ### Proposed functionality
  
  I would suggest to add contacts field to Virtual Machines table view/export, similarly to what we have in Devices. 
  Currently in Devices in the "Configure Table" it's possible to select "Contacts" as a column, but it's not available in Virtual Machines. 
  
  ### Use case
  
  When browsing through or exporting Virtual Machines it would be nice to be able to see who the owner/contact is. 
  
  ### Database changes
  
  _No response_
  
  ### External dependencies
  
  _No response_
  
  </issue>
  <code>
  [start of netbox/virtualization/tables/virtualmachines.py]
  1 import django_tables2 as tables
  2 
  3 from dcim.tables.devices import BaseInterfaceTable
  4 from netbox.tables import NetBoxTable, columns
  5 from tenancy.tables import TenancyColumnsMixin
  6 from virtualization.models import VirtualMachine, VMInterface
  7 
  8 __all__ = (
  9     'VirtualMachineTable',
  10     'VirtualMachineVMInterfaceTable',
  11     'VMInterfaceTable',
  12 )
  13 
  14 VMINTERFACE_BUTTONS = """
  15 {% if perms.ipam.add_ipaddress %}
  16     <a href="{% url 'ipam:ipaddress_add' %}?vminterface={{ record.pk }}&return_url={% url 'virtualization:virtualmachine_interfaces' pk=object.pk %}" class="btn btn-sm btn-success" title="Add IP Address">
  17         <i class="mdi mdi-plus-thick" aria-hidden="true"></i>
  18     </a>
  19 {% endif %}
  20 """
  21 
  22 
  23 #
  24 # Virtual machines
  25 #
  26 
  27 class VirtualMachineTable(TenancyColumnsMixin, NetBoxTable):
  28     name = tables.Column(
  29         order_by=('_name',),
  30         linkify=True
  31     )
  32     status = columns.ChoiceFieldColumn()
  33     cluster = tables.Column(
  34         linkify=True
  35     )
  36     role = columns.ColoredLabelColumn()
  37     comments = columns.MarkdownColumn()
  38     primary_ip4 = tables.Column(
  39         linkify=True,
  40         verbose_name='IPv4 Address'
  41     )
  42     primary_ip6 = tables.Column(
  43         linkify=True,
  44         verbose_name='IPv6 Address'
  45     )
  46     primary_ip = tables.Column(
  47         linkify=True,
  48         order_by=('primary_ip4', 'primary_ip6'),
  49         verbose_name='IP Address'
  50     )
  51     tags = columns.TagColumn(
  52         url_name='virtualization:virtualmachine_list'
  53     )
  54 
  55     class Meta(NetBoxTable.Meta):
  56         model = VirtualMachine
  57         fields = (
  58             'pk', 'id', 'name', 'status', 'cluster', 'role', 'tenant', 'tenant_group', 'platform', 'vcpus', 'memory', 'disk',
  59             'primary_ip4', 'primary_ip6', 'primary_ip', 'comments', 'tags', 'created', 'last_updated',
  60         )
  61         default_columns = (
  62             'pk', 'name', 'status', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk', 'primary_ip',
  63         )
  64 
  65 
  66 #
  67 # VM components
  68 #
  69 
  70 class VMInterfaceTable(BaseInterfaceTable):
  71     virtual_machine = tables.Column(
  72         linkify=True
  73     )
  74     name = tables.Column(
  75         linkify=True
  76     )
  77     vrf = tables.Column(
  78         linkify=True
  79     )
  80     contacts = columns.ManyToManyColumn(
  81         linkify_item=True
  82     )
  83     tags = columns.TagColumn(
  84         url_name='virtualization:vminterface_list'
  85     )
  86 
  87     class Meta(NetBoxTable.Meta):
  88         model = VMInterface
  89         fields = (
  90             'pk', 'id', 'name', 'virtual_machine', 'enabled', 'mac_address', 'mtu', 'mode', 'description', 'tags',
  91             'vrf', 'ip_addresses', 'fhrp_groups', 'untagged_vlan', 'tagged_vlans', 'contacts', 'created',
  92             'last_updated',
  93         )
  94         default_columns = ('pk', 'name', 'virtual_machine', 'enabled', 'description')
  95 
  96 
  97 class VirtualMachineVMInterfaceTable(VMInterfaceTable):
  98     parent = tables.Column(
  99         linkify=True
  100     )
  101     bridge = tables.Column(
  102         linkify=True
  103     )
  104     actions = columns.ActionsColumn(
  105         actions=('edit', 'delete'),
  106         extra_buttons=VMINTERFACE_BUTTONS
  107     )
  108 
  109     class Meta(NetBoxTable.Meta):
  110         model = VMInterface
  111         fields = (
  112             'pk', 'id', 'name', 'enabled', 'parent', 'bridge', 'mac_address', 'mtu', 'mode', 'description', 'tags',
  113             'ip_addresses', 'fhrp_groups', 'untagged_vlan', 'tagged_vlans', 'actions',
  114         )
  115         default_columns = ('pk', 'name', 'enabled', 'mac_address', 'mtu', 'mode', 'description', 'ip_addresses')
  116         row_attrs = {
  117             'data-name': lambda record: record.name,
  118         }
  119
  [end of netbox/virtualization/tables/virtualmachines.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/netbox/virtualization/tables/virtualmachines.py b/netbox/virtualization/tables/virtualmachines.py
  --- a/netbox/virtualization/tables/virtualmachines.py
  +++ b/netbox/virtualization/tables/virtualmachines.py
  @@ -48,6 +48,9 @@
           order_by=('primary_ip4', 'primary_ip6'),
           verbose_name='IP Address'
       )
  +    contacts = columns.ManyToManyColumn(
  +        linkify_item=True
  +    )
       tags = columns.TagColumn(
           url_name='virtualization:virtualmachine_list'
       )
  @@ -56,7 +59,7 @@
           model = VirtualMachine
           fields = (
               'pk', 'id', 'name', 'status', 'cluster', 'role', 'tenant', 'tenant_group', 'platform', 'vcpus', 'memory', 'disk',
  -            'primary_ip4', 'primary_ip6', 'primary_ip', 'comments', 'tags', 'created', 'last_updated',
  +            'primary_ip4', 'primary_ip6', 'primary_ip', 'comments', 'contacts', 'tags', 'created', 'last_updated',
           )
           default_columns = (
               'pk', 'name', 'status', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk', 'primary_ip',
  
verification_info: {"golden_diff": "diff --git a/netbox/virtualization/tables/virtualmachines.py b/netbox/virtualization/tables/virtualmachines.py\n--- a/netbox/virtualization/tables/virtualmachines.py\n+++ b/netbox/virtualization/tables/virtualmachines.py\n@@ -48,6 +48,9 @@\n         order_by=('primary_ip4', 'primary_ip6'),\n         verbose_name='IP Address'\n     )\n+    contacts = columns.ManyToManyColumn(\n+        linkify_item=True\n+    )\n     tags = columns.TagColumn(\n         url_name='virtualization:virtualmachine_list'\n     )\n@@ -56,7 +59,7 @@\n         model = VirtualMachine\n         fields = (\n             'pk', 'id', 'name', 'status', 'cluster', 'role', 'tenant', 'tenant_group', 'platform', 'vcpus', 'memory', 'disk',\n-            'primary_ip4', 'primary_ip6', 'primary_ip', 'comments', 'tags', 'created', 'last_updated',\n+            'primary_ip4', 'primary_ip6', 'primary_ip', 'comments', 'contacts', 'tags', 'created', 'last_updated',\n         )\n         default_columns = (\n             'pk', 'name', 'status', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk', 'primary_ip',\n", "issue": "Add Contacts field to Virtual Machines table view\n### NetBox version\n\nv3.2.7\n\n### Feature type\n\nChange to existing functionality\n\n### Proposed functionality\n\nI would suggest to add contacts field to Virtual Machines table view/export, similarly to what we have in Devices. \r\nCurrently in Devices in the \"Configure Table\" it's possible to select \"Contacts\" as a column, but it's not available in Virtual Machines. \n\n### Use case\n\nWhen browsing through or exporting Virtual Machines it would be nice to be able to see who the owner/contact is. \n\n### Database changes\n\n_No response_\n\n### External dependencies\n\n_No response_\n", "before_files": [{"content": "import django_tables2 as tables\n\nfrom dcim.tables.devices import BaseInterfaceTable\nfrom netbox.tables import NetBoxTable, columns\nfrom tenancy.tables import TenancyColumnsMixin\nfrom virtualization.models import VirtualMachine, VMInterface\n\n__all__ = (\n    'VirtualMachineTable',\n    'VirtualMachineVMInterfaceTable',\n    'VMInterfaceTable',\n)\n\nVMINTERFACE_BUTTONS = \"\"\"\n{% if perms.ipam.add_ipaddress %}\n    <a href=\"{% url 'ipam:ipaddress_add' %}?vminterface={{ record.pk }}&return_url={% url 'virtualization:virtualmachine_interfaces' pk=object.pk %}\" class=\"btn btn-sm btn-success\" title=\"Add IP Address\">\n        <i class=\"mdi mdi-plus-thick\" aria-hidden=\"true\"></i>\n    </a>\n{% endif %}\n\"\"\"\n\n\n#\n# Virtual machines\n#\n\nclass VirtualMachineTable(TenancyColumnsMixin, NetBoxTable):\n    name = tables.Column(\n        order_by=('_name',),\n        linkify=True\n    )\n    status = columns.ChoiceFieldColumn()\n    cluster = tables.Column(\n        linkify=True\n    )\n    role = columns.ColoredLabelColumn()\n    comments = columns.MarkdownColumn()\n    primary_ip4 = tables.Column(\n        linkify=True,\n        verbose_name='IPv4 Address'\n    )\n    primary_ip6 = tables.Column(\n        linkify=True,\n        verbose_name='IPv6 Address'\n    )\n    primary_ip = tables.Column(\n        linkify=True,\n        order_by=('primary_ip4', 'primary_ip6'),\n        verbose_name='IP Address'\n    )\n    tags = columns.TagColumn(\n        url_name='virtualization:virtualmachine_list'\n    )\n\n    class Meta(NetBoxTable.Meta):\n        model = VirtualMachine\n        fields = (\n            'pk', 'id', 'name', 'status', 'cluster', 'role', 'tenant', 'tenant_group', 'platform', 'vcpus', 'memory', 'disk',\n            'primary_ip4', 'primary_ip6', 'primary_ip', 'comments', 'tags', 'created', 'last_updated',\n        )\n        default_columns = (\n            'pk', 'name', 'status', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk', 'primary_ip',\n        )\n\n\n#\n# VM components\n#\n\nclass VMInterfaceTable(BaseInterfaceTable):\n    virtual_machine = tables.Column(\n        linkify=True\n    )\n    name = tables.Column(\n        linkify=True\n    )\n    vrf = tables.Column(\n        linkify=True\n    )\n    contacts = columns.ManyToManyColumn(\n        linkify_item=True\n    )\n    tags = columns.TagColumn(\n        url_name='virtualization:vminterface_list'\n    )\n\n    class Meta(NetBoxTable.Meta):\n        model = VMInterface\n        fields = (\n            'pk', 'id', 'name', 'virtual_machine', 'enabled', 'mac_address', 'mtu', 'mode', 'description', 'tags',\n            'vrf', 'ip_addresses', 'fhrp_groups', 'untagged_vlan', 'tagged_vlans', 'contacts', 'created',\n            'last_updated',\n        )\n        default_columns = ('pk', 'name', 'virtual_machine', 'enabled', 'description')\n\n\nclass VirtualMachineVMInterfaceTable(VMInterfaceTable):\n    parent = tables.Column(\n        linkify=True\n    )\n    bridge = tables.Column(\n        linkify=True\n    )\n    actions = columns.ActionsColumn(\n        actions=('edit', 'delete'),\n        extra_buttons=VMINTERFACE_BUTTONS\n    )\n\n    class Meta(NetBoxTable.Meta):\n        model = VMInterface\n        fields = (\n            'pk', 'id', 'name', 'enabled', 'parent', 'bridge', 'mac_address', 'mtu', 'mode', 'description', 'tags',\n            'ip_addresses', 'fhrp_groups', 'untagged_vlan', 'tagged_vlans', 'actions',\n        )\n        default_columns = ('pk', 'name', 'enabled', 'mac_address', 'mtu', 'mode', 'description', 'ip_addresses')\n        row_attrs = {\n            'data-name': lambda record: record.name,\n        }\n", "path": "netbox/virtualization/tables/virtualmachines.py"}]}