internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: netbox-community/netbox

Issue:
Changing event rule action type messes up Conditions field
### Deployment Type

Self-hosted

### NetBox Version

v3.7.1

### Python Version

3.11

### Steps to Reproduce

1. Go to **Operations - Event Rules - Add**
2. Set Conditions = `{ "and": [{"attr": "status.value", "value": "deprecated"}]}`
3. Select Action type = Script

### Expected Behavior

Conditions field stays as-is

### Observed Behavior

Conditions field is rewritten as invalid JSON:

`"{ \"and\": [{\"attr\": \"status.value\", \"value\": \"deprecated\"}]}"`

The quoting is added with every change of the Action type.

This also happens if editing an existing event rule and changing the Action type.

### Workaround

- Copy the Conditions field somewhere
- Change the Action type
- Paste the Conditions field back


Discussion:
Btw, the error message (that happens if the event rule with the modified Conditions is saved) is slightly incorrect:

**Ruleset must be a dictionary, not <class 'django.forms.fields.JSONString'>.
Enter conditions in [JSON](https://json.org/) format.**

A Python dictionary is not necessarily valid JSON (take for example `None` vs. `null`, or single-quotes vs. double-quotes)
This is occurring because the initial data passed as a query parameter when re-rendering the form is interpreted as a string and automatically escaped. The same behavior can be observed by manually passing initial data to the form. For instance, `GET /extras/event-rules/add/?conditions={"foo": 123}` populates the value `"{\"foo\": 123}"` (a string) into the conditions field.

We need some logic in place to detect and load initial data as JSON, rather than treating it as a string. @DanSheps I'm going to take this one if you don't mind as I think we can fix this pretty easily under the field class' `prepare_value()` method.

Resolving patch:
diff --git a/netbox/utilities/forms/fields/fields.py b/netbox/utilities/forms/fields/fields.py
--- a/netbox/utilities/forms/fields/fields.py
+++ b/netbox/utilities/forms/fields/fields.py
@@ -105,7 +105,12 @@ def prepare_value(self, value):
             return value
         if value in ('', None):
             return ''
-        return json.dumps(value, sort_keys=True, indent=4)
+        if type(value) is str:
+            try:
+                value = json.loads(value, cls=self.decoder)
+            except json.decoder.JSONDecodeError:
+                return value
+        return json.dumps(value, sort_keys=True, indent=4, ensure_ascii=False, cls=self.encoder)
 
 
 class MACAddressField(forms.Field):


Test patch:
Repository: netbox-community/netbox

Issue:
Typo in DataSourceBulkEditForm
### Deployment Type

Self-hosted

### NetBox Version

v3.7.1

### Python Version

3.8

### Steps to Reproduce

"lavel" is defined as "Enforce unique space", but I think the correct definition is "Enabled".

https://github.com/netbox-community/netbox/blob/487f1ccfde26ef3c1f8a28089826acc0cd6fadb2/netbox/core/forms/bulk_edit.py#L21-L25

- Add a new data source
![demo netbox dev_core_data-sources_add_](https://github.com/netbox-community/netbox/assets/20819471/226bd748-eab2-4d42-9b13-3d6ae925b675)

- Editing 1 Data Sources
![demo netbox dev_core_data-sources_edit_](https://github.com/netbox-community/netbox/assets/20819471/42778f93-814b-460b-8dee-00ebf194e0ac)


### Expected Behavior

Enabled

### Observed Behavior

Enforce unique space


Discussion:

Resolving patch:
diff --git a/netbox/core/forms/bulk_edit.py b/netbox/core/forms/bulk_edit.py
--- a/netbox/core/forms/bulk_edit.py
+++ b/netbox/core/forms/bulk_edit.py
@@ -21,7 +21,7 @@ class DataSourceBulkEditForm(NetBoxModelBulkEditForm):
     enabled = forms.NullBooleanField(
         required=False,
         widget=BulkEditNullBooleanSelect(),
-        label=_('Enforce unique space')
+        label=_('Enabled')
     )
     description = forms.CharField(
         label=_('Description'),


Test patch:
Repository: netbox-community/netbox

Issue:
Typo in PowerOutletImportForm
### Deployment Type

Self-hosted

### NetBox Version

v3.7.1

### Python Version

3.8

### Steps to Reproduce

"lavel" is defined as "Feed lag", but I think the correct definition is "Feed leg".
https://github.com/netbox-community/netbox/blob/ba755221bbfb167352312e988c518fba3414bbbf/netbox/dcim/forms/bulk_import.py#L729-L734

### Expected Behavior

Feed leg

### Observed Behavior

Feed lag


Discussion:

Resolving patch:
diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py
--- a/netbox/dcim/forms/bulk_import.py
+++ b/netbox/dcim/forms/bulk_import.py
@@ -727,7 +727,7 @@ class PowerOutletImportForm(NetBoxModelImportForm):
         help_text=_('Local power port which feeds this outlet')
     )
     feed_leg = CSVChoiceField(
-        label=_('Feed lag'),
+        label=_('Feed leg'),
         choices=PowerOutletFeedLegChoices,
         required=False,
         help_text=_('Electrical phase (for three-phase circuits)')


Test patch:
Repository: netbox-community/netbox

Issue:
`can_add()` template filter raises exception when passing a model
### Deployment Type

NetBox Cloud

### NetBox Version

v3.7.1

### Python Version

3.11

### Steps to Reproduce

There is an issue with how the `can_add()` filter evaluates permissions. It should expect to receive a model rather than a specific instance (as an existing instance obviously cannot be create again). The following template code fails:

```
{% load perms %}
{% if request.user|can_add:model %}
```

Below is a reconstruction using the Python shell:

```python
>>> from utilities.templatetags.perms import can_add
>>> user=User.objects.get(username='bob')
>>> user.has_perm('dcim.add_poweroutlet')
True
>>> can_add(user, PowerOutlet)
Traceback (most recent call last):
  File "/home/jstretch/projects/netbox/venv/lib/python3.10/site-packages/django/db/models/fields/__init__.py", line 2053, in get_prep_value
    return int(value)
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'property'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  ...
  File "/home/jstretch/projects/netbox/venv/lib/python3.10/site-packages/django/db/models/fields/__init__.py", line 2055, in get_prep_value
    raise e.__class__(
TypeError: Field 'id' expected a number but got <property object at 0x7fa360779760>.
```

### Expected Behavior

Passing a model to the `can_add()` filter should successfully evaluate the user's permission to create a new instance of that model.

### Observed Behavior

A `TypeError` exception is raised.


Discussion:

Resolving patch:
diff --git a/netbox/utilities/templatetags/perms.py b/netbox/utilities/templatetags/perms.py
--- a/netbox/utilities/templatetags/perms.py
+++ b/netbox/utilities/templatetags/perms.py
@@ -24,8 +24,9 @@ def can_view(user, instance):
 
 
 @register.filter()
-def can_add(user, instance):
-    return _check_permission(user, instance, 'add')
+def can_add(user, model):
+    permission = get_permission_for_model(model, 'add')
+    return user.has_perm(perm=permission)
 
 
 @register.filter()


Test patch:
Repository: netbox-community/netbox

Issue:
Select All check box in device Types Interfaces fails to check all boxes
### Deployment Type

Self-hosted

### NetBox Version

v3.7.0

### Python Version

3.8

### Steps to Reproduce

1. Create a device Template with more than 50 interfaces
2. Go to Device Types
3. Click name of device-type
4. Click on Interfaces
5. Click on per page widget to allow 100 lines to be displayed
6. Click on Check box next to name column

### Expected Behavior

All the checkboxes should be selected.

### Observed Behavior

Only the signle box next to name is selected.


Discussion:
I also noticed that navigating between Interfaces and Console Ports or Power Ports, the All check box next to Name will  start functioning again, but the Number of lines widget setting is not preserved.
It looks like the "select all" event handler isn't getting reinitialized after the table is re-rendered via an HTMX request (e.g. changing the ordering or pagination length).
There's a bug in how event handlers are added to the dynamic object list. HTMX controls within the table reference the HTMX container as `closest .htmx-container`, but this is obviously relative. When `initHtmx()` attempts to resolves this, it fails. It only works on the regular object list view because the quick search field coincidentally refers to the container by its explicit ID (`#object_list`); the quick search field is not present on the device type components list.

Resolving patch:
diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py
--- a/netbox/dcim/views.py
+++ b/netbox/dcim/views.py
@@ -58,7 +58,11 @@ def get_children(self, request, parent):
         return self.child_model.objects.restrict(request.user, 'view').filter(device=parent)
 
 
-class DeviceTypeComponentsView(DeviceComponentsView):
+class DeviceTypeComponentsView(generic.ObjectChildrenView):
+    actions = {
+        **DEFAULT_ACTION_PERMISSIONS,
+        'bulk_rename': {'change'},
+    }
     queryset = DeviceType.objects.all()
     template_name = 'dcim/devicetype/component_templates.html'
     viewname = None  # Used for return_url resolution


Test patch:
Repository: netbox-community/netbox

Issue:
Typo in Device model
### Deployment Type

Self-hosted

### NetBox Version

v3.7.2

### Python Version

3.8

### Steps to Reproduce

error message is defined as "A U0 device type ...", but I think the correct definition is "A 0U device type ...".

https://github.com/netbox-community/netbox/blob/011bc5bd78229122341bf21f0774662413dd8ba0/netbox/dcim/models/devices.py#L873-L880

### Expected Behavior

A 0U device type ({device_type}) cannot be assigned to a rack position.

### Observed Behavior

A U0 device type ({device_type}) cannot be assigned to a rack position.


Discussion:

Resolving patch:
diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py
--- a/netbox/dcim/models/devices.py
+++ b/netbox/dcim/models/devices.py
@@ -875,7 +875,7 @@ def clean(self):
             if self.position and self.device_type.u_height == 0:
                 raise ValidationError({
                     'position': _(
-                        "A U0 device type ({device_type}) cannot be assigned to a rack position."
+                        "A 0U device type ({device_type}) cannot be assigned to a rack position."
                     ).format(device_type=self.device_type)
                 })
 


Test patch:
Repository: netbox-community/netbox

Issue:
FHRP group ID is misrepresented on the group assignments API endpoint when brief mode is used
### Deployment Type

NetBox Cloud

### NetBox Version

v3.7.2

### Python Version

3.11

### Steps to Reproduce

1. Create an FHRP group
2. Assigned FHRP group to a device interface (details are unimportant)
3. Query the `/api/ipam/fhrp-group-assignments/` REST API endpoint
4. Make a second query to the endpoint, this time using brief mode `?brief=true`
5. Compare the results, specifically the `group` field

Example results for reference:

#### Normal mode
```
{
    "id": 1,
    "url": "http://netbox:8000/api/ipam/fhrp-group-assignments/1/",
    "display": "GigabitEthernet1/0/3: foobar123 VRRPv3: 10 (1)",
    "group": {
        "id": 1,
        "url": "http://netbox:8000/api/ipam/fhrp-groups/1/",
        "display": "foobar123 VRRPv3: 10",
        "protocol": "vrrp3",
        "group_id": 10
    },
    "interface_type": "dcim.interface",
    "interface_id": 172,
    "interface": {
        ...
    },
    "priority": 1,
    "created": "2024-02-13T13:55:10.906366Z",
    "last_updated": "2024-02-13T13:55:10.906373Z"
}
```

#### Brief mode
```
{
    "id": 1,
    "url": "http://netbox:8000/api/ipam/fhrp-group-assignments/1/",
    "display": "GigabitEthernet1/0/3: foobar123 VRRPv3: 10 (1)",
    "interface_type": 39,
    "interface_id": 172,
    "group_id": 1,
    "priority": 1
}
```

### Expected Behavior

The `group` field should be present in and consistent between both responses.

### Observed Behavior

The `group` field is omitted in the brief mode response, and a `group_id` field is included instead. Note that this is **not** the numeric group ID assigned by the user to the FHRP group, but rather the unique database ID for the group object.


Discussion:

Resolving patch:
diff --git a/netbox/ipam/api/nested_serializers.py b/netbox/ipam/api/nested_serializers.py
--- a/netbox/ipam/api/nested_serializers.py
+++ b/netbox/ipam/api/nested_serializers.py
@@ -116,10 +116,11 @@ class Meta:
 
 class NestedFHRPGroupAssignmentSerializer(WritableNestedSerializer):
     url = serializers.HyperlinkedIdentityField(view_name='ipam-api:fhrpgroupassignment-detail')
+    group = NestedFHRPGroupSerializer()
 
     class Meta:
         model = models.FHRPGroupAssignment
-        fields = ['id', 'url', 'display', 'interface_type', 'interface_id', 'group_id', 'priority']
+        fields = ['id', 'url', 'display', 'group', 'interface_type', 'interface_id', 'priority']
 
 
 #


Test patch:
diff --git a/netbox/ipam/tests/test_api.py b/netbox/ipam/tests/test_api.py
--- a/netbox/ipam/tests/test_api.py
+++ b/netbox/ipam/tests/test_api.py
@@ -760,7 +760,7 @@ def setUpTestData(cls):
 
 class FHRPGroupAssignmentTest(APIViewTestCases.APIViewTestCase):
     model = FHRPGroupAssignment
-    brief_fields = ['display', 'group_id', 'id', 'interface_id', 'interface_type', 'priority', 'url']
+    brief_fields = ['display', 'group', 'id', 'interface_id', 'interface_type', 'priority', 'url']
     bulk_update_data = {
         'priority': 100,
     }
Repository: netbox-community/netbox

Issue:
Tunnel Group is not selectable as column in VPN tunnels list
### Deployment Type

Self-hosted

### NetBox Version

v3.7.2

### Python Version

3.11

### Steps to Reproduce

1. Go to VPN - Tunnels
2. Click Configure Table


### Expected Behavior

There is the Tunnel Group column

### Observed Behavior

There is no Tunnel Group column that could be shown


Discussion:

Resolving patch:
diff --git a/netbox/vpn/tables/tunnels.py b/netbox/vpn/tables/tunnels.py
--- a/netbox/vpn/tables/tunnels.py
+++ b/netbox/vpn/tables/tunnels.py
@@ -40,6 +40,10 @@ class TunnelTable(TenancyColumnsMixin, NetBoxTable):
         verbose_name=_('Name'),
         linkify=True
     )
+    group = tables.Column(
+        verbose_name=_('Group'),
+        linkify=True
+    )
     status = columns.ChoiceFieldColumn(
         verbose_name=_('Status')
     )
@@ -63,10 +67,10 @@ class TunnelTable(TenancyColumnsMixin, NetBoxTable):
     class Meta(NetBoxTable.Meta):
         model = Tunnel
         fields = (
-            'pk', 'id', 'name', 'status', 'encapsulation', 'ipsec_profile', 'tenant', 'tenant_group', 'tunnel_id',
-            'termination_count', 'description', 'comments', 'tags', 'created', 'last_updated',
+            'pk', 'id', 'name', 'group', 'status', 'encapsulation', 'ipsec_profile', 'tenant', 'tenant_group',
+            'tunnel_id', 'termination_count', 'description', 'comments', 'tags', 'created', 'last_updated',
         )
-        default_columns = ('pk', 'name', 'status', 'encapsulation', 'tenant', 'terminations_count')
+        default_columns = ('pk', 'name', 'group', 'status', 'encapsulation', 'tenant', 'terminations_count')
 
 
 class TunnelTerminationTable(TenancyColumnsMixin, NetBoxTable):


Test patch:
Repository: netbox-community/netbox

Issue:
API call to add VPN tunnel fails: group field is required
### Deployment Type

Self-hosted

### NetBox Version

v3.7.2

### Python Version

3.11

### Steps to Reproduce

```
$ curl -s -i http://netbox-test.lein.io/api/vpn/tunnels/ \
-H "Authorization: Token 176d4c04ccc8f2a549ea6fd393567d9da5a796ff" \
-H "Content-type: application/json" \
-H "Accept: application/json; indent=4" \
-d '{"name":"TestTunnel", "encapsulation":"ipsec-tunnel", "status":"active"}'
```

### Expected Behavior

Tunnel "TestTunnel" is added successfully.

### Observed Behavior

```
HTTP/1.1 400 Bad Request
API-Version: 3.7
...
{
    "group": [
        "This field is required."
    ]
}
```

Adding the same tunnel in GUI is successful (using only those three mandatory fields).

### Workaround

Create a tunnel group like "TEMP", then add `"group":1` (where 1 is the group ID) in the create call, and finally edit the resulted tunnel to remove the TEMP group.


Discussion:

Resolving patch:
diff --git a/netbox/vpn/api/serializers.py b/netbox/vpn/api/serializers.py
--- a/netbox/vpn/api/serializers.py
+++ b/netbox/vpn/api/serializers.py
@@ -46,7 +46,10 @@ class TunnelSerializer(NetBoxModelSerializer):
     status = ChoiceField(
         choices=TunnelStatusChoices
     )
-    group = NestedTunnelGroupSerializer()
+    group = NestedTunnelGroupSerializer(
+        required=False,
+        allow_null=True
+    )
     encapsulation = ChoiceField(
         choices=TunnelEncapsulationChoices
     )


Test patch:
diff --git a/netbox/vpn/tests/test_api.py b/netbox/vpn/tests/test_api.py
--- a/netbox/vpn/tests/test_api.py
+++ b/netbox/vpn/tests/test_api.py
@@ -105,7 +105,6 @@ def setUpTestData(cls):
             {
                 'name': 'Tunnel 6',
                 'status': TunnelStatusChoices.STATUS_DISABLED,
-                'group': tunnel_groups[1].pk,
                 'encapsulation': TunnelEncapsulationChoices.ENCAP_GRE,
             },
         ]
Repository: netbox-community/netbox

Issue:
Server Error when creating permission with constraints
### Deployment Type

Self-hosted

### NetBox Version

v3.7.1

### Python Version

3.10

### Steps to Reproduce

1. Add new Permission https://demo.netbox.dev/users/permissions/add/ 
2. Setup **Constraints** as `{"role": "server"}`
3. Create
4. Obtain Server Error
```
<class 'ValueError'>

Field 'id' expected a number but got 'server'.

Python version: 3.8.10
NetBox version: 3.7.1
Plugins: 
  netbox_demo: 0.3.1
```

### Expected Behavior

Server Error 500 should not be raised. 
It should display some kind of validation popup.


### Observed Behavior

Server Error occurs
```
<class 'ValueError'>

Field 'id' expected a number but got 'server'.

Python version: 3.8.10
NetBox version: 3.7.1
Plugins: 
  netbox_demo: 0.3.1
```


Discussion:
Recreated from #15017 because I cannot reopen the issue. 
I suppose the problem still needs to be fixed.
See: #15019 

Resolving patch:
diff --git a/netbox/users/forms/model_forms.py b/netbox/users/forms/model_forms.py
--- a/netbox/users/forms/model_forms.py
+++ b/netbox/users/forms/model_forms.py
@@ -385,7 +385,7 @@ def clean(self):
                         CONSTRAINT_TOKEN_USER: 0,  # Replace token with a null user ID
                     }
                     model.objects.filter(qs_filter_from_constraints(constraints, tokens)).exists()
-                except FieldError as e:
+                except (FieldError, ValueError) as e:
                     raise forms.ValidationError({
                         'constraints': _('Invalid filter for {model}: {error}').format(model=model, error=e)
                     })


Test patch:
Repository: netbox-community/netbox

Issue:
Exception raised when uploading invalid device bay CSV
### Deployment Type

Self-hosted

### NetBox Version

v3.7.2

### Python Version

3.8

### Steps to Reproduce

1. Go to `/dcim/device-bays/import/` (from left menu: Devices > Device Bays > Upload) 
2. Paste in the following data, select format as "CSV", then Submit.

Case 1:

```
name
foo
```

Case 2:

```
name,device
foo,blah-nonexistent
```


### Expected Behavior

A meaningful error message. In the first case, something like "missing column `device`". In the second case, something like "device "blah-nonexistent" does not exist"

### Observed Behavior

A RelatedObjectDoesNotExist exception is raised.

```
<class 'dcim.models.device_components.DeviceBay.device.RelatedObjectDoesNotExist'>

DeviceBay has no device.

Python version: 3.8.10
NetBox version: 3.7.2
```



Discussion:
Note: these errors *are* properly handled when uploading Interfaces.

Case 1:

```
name
foo
```
![image](https://github.com/netbox-community/netbox/assets/44789/e8dd6e47-aaa8-4b95-b575-61cf7d30c42c)

Case 2:

```
name,type,device
foo,virtual,blah-nonexistent
```
![image](https://github.com/netbox-community/netbox/assets/44789/e967d208-5de9-4258-a4d9-7aadc34fc940)


Resolving patch:
diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py
--- a/netbox/dcim/forms/bulk_import.py
+++ b/netbox/dcim/forms/bulk_import.py
@@ -996,7 +996,7 @@ def __init__(self, *args, **kwargs):
                 device_type__subdevice_role=SubdeviceRoleChoices.ROLE_CHILD
             ).exclude(pk=device.pk)
         else:
-            self.fields['installed_device'].queryset = Interface.objects.none()
+            self.fields['installed_device'].queryset = Device.objects.none()
 
 
 class InventoryItemImportForm(NetBoxModelImportForm):
diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py
--- a/netbox/dcim/models/device_components.py
+++ b/netbox/dcim/models/device_components.py
@@ -1133,13 +1133,13 @@ def clean(self):
         super().clean()
 
         # Validate that the parent Device can have DeviceBays
-        if not self.device.device_type.is_parent_device:
+        if hasattr(self, 'device') and not self.device.device_type.is_parent_device:
             raise ValidationError(_("This type of device ({device_type}) does not support device bays.").format(
                 device_type=self.device.device_type
             ))
 
         # Cannot install a device into itself, obviously
-        if self.device == self.installed_device:
+        if self.installed_device and getattr(self, 'device', None) == self.installed_device:
             raise ValidationError(_("Cannot install a device into itself."))
 
         # Check that the installed device is not already installed elsewhere


Test patch:
Repository: netbox-community/netbox

Issue:
Wrong filter used when clicking number of IP addresses in VM Interface table
### Deployment Type

Self-hosted

### NetBox Version

v3.7.2

### Python Version

3.8

### Steps to Reproduce

Make sure you use a Virtual Machine, that has an interface with 3 or more IP addresses assigned to it.
1. Go to a Virtual Machine page
2. Go to interfaces tab
3. There should be an interface with 3 or more IP addresses
  a. Instead of it showing the individual IP addresses in the table, it will show you the number of IP addresses. (Clickable link)
4. Click link with number of IP addresses

### Expected Behavior

It should link you to a filtered page that shows the IP addresses associated with the VM Interface

### Observed Behavior

It links you to the right page, but as observed in the URL, it uses the wrong filter and attempts to filter for "regular" physical interfaces, so it gives you either an empty set of results, or the wrong results.

Example URL: https://netbox.xxxxxxx/ipam/ip-addresses/?interface_id=195


Discussion:
I was able to reproduce the issue on the public Netbox demo. 
~https://demo.netbox.dev/virtualization/virtual-machines/544/interfaces/~ (expired)

Resolving patch:
diff --git a/netbox/dcim/tables/template_code.py b/netbox/dcim/tables/template_code.py
--- a/netbox/dcim/tables/template_code.py
+++ b/netbox/dcim/tables/template_code.py
@@ -37,7 +37,7 @@
 INTERFACE_IPADDRESSES = """
 <div class="table-badge-group">
   {% if value.count >= 3 %}
-    <a href="{% url 'ipam:ipaddress_list' %}?interface_id={{ record.pk }}">{{ value.count }}</a>
+    <a href="{% url 'ipam:ipaddress_list' %}?{{ record|meta:"model_name" }}_id={{ record.pk }}">{{ value.count }}</a>
   {% else %}
     {% for ip in value.all %}
       {% if ip.status != 'active' %}


Test patch: