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

Issue:
N+1 issue on the /api/ipam/ip-addresses/ endpoint
### Deployment Type

Self-hosted

### NetBox Version

v3.7.6

### Python Version

3.10

### Steps to Reproduce

Call the  `/api/ipam/ip-addresses/` endpoint with more than 1 assigned ip address in the database (important that the ip addresses are assigned and you are listing assigned ip addresses, for example by using `assigned_to_interface=true` filter)

### Expected Behavior

No N+1 issue.

I can submit I PR if wanted (I think the issue is that `IPAddressViewSet` are missing `assigned_object_type` in the `prefetch_related`)

### Observed Behavior

N+1 issue with the following query:

`SELECT ••• FROM "django_content_type" WHERE "django_content_type"."id" = X LIMIT 21`


Discussion:
Thank you for opening a bug report. I was unable to reproduce the reported behavior on NetBox v3.7.6. Please re-confirm the reported behavior on the current stable release and adjust your post above as necessary. Remember to provide detailed steps that someone else can follow using a clean installation of NetBox to reproduce the issue. Remember to include the steps taken to create any initial objects or other data.
@jeremystretch - forgot to mention that the ips must be assigned. I've updated the post now above + also verified that the issue also affects 3.7.6

As a reference, I created ips like this to reproduce the issue:
```
IPAddress.objects.create(
    address=ip,
    assigned_object_type=ContentType.objects.get(app_label="dcim", model="interface"),
    assigned_object_id=52,
)
```

@jeremystretch - I can fix a PR for this
@mulmat thanks, I've assigned this to you. A word of caution: be aware that the tables wipe out any prefetches set on the view's queryset, so addressing this will likely need work on the column itself.

Resolving patch:
diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py
--- a/netbox/ipam/api/views.py
+++ b/netbox/ipam/api/views.py
@@ -119,7 +119,7 @@ class IPRangeViewSet(NetBoxModelViewSet):
 
 class IPAddressViewSet(NetBoxModelViewSet):
     queryset = IPAddress.objects.prefetch_related(
-        'vrf__tenant', 'tenant', 'nat_inside', 'nat_outside', 'tags', 'assigned_object'
+        'vrf__tenant', 'tenant', 'nat_inside', 'nat_outside', 'tags', 'assigned_object', 'assigned_object_type'
     )
     serializer_class = serializers.IPAddressSerializer
     filterset_class = filtersets.IPAddressFilterSet


Test patch:
Repository: netbox-community/netbox

Issue:
false positive related object in custom fields
### Deployment Type

Self-hosted

### NetBox Version

v3.7.4

### Python Version

3.10

### Steps to Reproduce

1. Create new custom field.
2. Try to delete the newly created custom field.
3. There is a message that the related object "CustomField_content_types object (n)" will also get deleted.

### Expected Behavior

Newly created custom field isn't bound to any object, so user should get simple delete confirmation dialog without related objects.

### Observed Behavior

User gets delete confirmation dialog with related objects even though those kinds of objects don't exist.

Another observation, don't know if it is this issue related:
During the upgrade procedure to the feature branch, I get the following error mentioning the customfield_content_types: 

```
File "/opt/netbox/venv/lib/python3.10/site-packages/psycopg/cursor.py", line 732, in execute
    raise ex.with_traceback(None)
django.db.utils.ProgrammingError: relation "extras_customfield_content_types_id_seq" does not exist

```


Discussion:
> User gets delete confirmation dialog with related objects even though those kinds of objects don't exist.

This is not that it is bound to a specific object, it is just stating that the custom field has a relation to the django content type table.

Technically, it is not incorrect, but I agree we should probably exempt the contenttype field from the relationship check on deletion, at least for this specific case.
Thanks for clarification Dan. 

Did you check, whether it has something to do with the failure of the upgrade to the feature branch? 
> Did you check, whether it has something to do with the failure of the upgrade to the feature branch?

This would have nothing to do with it.

Please try a fresh upgrade and let us know if this fails still by opening a new bug.
Thank you Dan. I just tried the upgrade from 3.7.4 as well from 3.6.9 to new v4.0-beta1 and got the same error, so it seems it has nothing to do with it.
I will open a new bug issue.
Could you please assign it to me?


Resolving patch:
diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py
--- a/netbox/netbox/views/generic/object_views.py
+++ b/netbox/netbox/views/generic/object_views.py
@@ -339,10 +339,14 @@ def _get_dependent_objects(self, obj):
 
         # Compile a mapping of models to instances
         dependent_objects = defaultdict(list)
-        for model, instance in collector.instances_with_model():
+        for model, instances in collector.instances_with_model():
+            # Ignore relations to auto-created models (e.g. many-to-many mappings)
+            if model._meta.auto_created:
+                continue
             # Omit the root object
-            if instance != obj:
-                dependent_objects[model].append(instance)
+            if instances == obj:
+                continue
+            dependent_objects[model].append(instances)
 
         return dict(dependent_objects)
 


Test patch:
Repository: netbox-community/netbox

Issue:
Cache /api/schema/ endpoint
### NetBox version

v3.7.6

### Feature type

Change to existing functionality

### Proposed functionality

Add caching on the `/api/schema/ ` endpoint with a sane default (maybe 300 seconds?) and with the possibility to configure it in configuration.py

### Use case

Generating openapi schema takes some time, caching it would:

- Decrease response time when doing multiple calls to `/api/schema/`
- Lower the resources needed from application server (since less openapi schemas will be generated)

### Database changes

None

### External dependencies

None


Discussion:
I can own this if accepted
We actually used to cache the schema definition back in ~v2.11 (see #6423 and 257c0afdb5b62c7ea84159d2b46d53ce5a43f3a3), before we switched from drf-yasg to spectacular. Unfortunately I don't think spectacular offers caching support natively, so we'd have to implement it ourselves.

@mulmat happy to assign this to you to explore options. Let us know what you find!

Resolving patch:
diff --git a/netbox/netbox/urls.py b/netbox/netbox/urls.py
--- a/netbox/netbox/urls.py
+++ b/netbox/netbox/urls.py
@@ -1,6 +1,7 @@
 from django.conf import settings
 from django.conf.urls import include
 from django.urls import path
+from django.views.decorators.cache import cache_page
 from django.views.decorators.csrf import csrf_exempt
 from django.views.static import serve
 from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
@@ -56,7 +57,13 @@
     path('api/wireless/', include('wireless.api.urls')),
     path('api/status/', StatusView.as_view(), name='api-status'),
 
-    path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
+    path(
+        "api/schema/",
+        cache_page(timeout=86400, key_prefix=f"api_schema_{settings.VERSION}")(
+            SpectacularAPIView.as_view()
+        ),
+        name="schema",
+    ),
     path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='api_docs'),
     path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='api_redocs'),
 


Test patch:
Repository: netbox-community/netbox

Issue:
No Reverse Match for l2vpntermination_list
### Deployment Type

Self-hosted

### NetBox Version

3.7.3

### Python Version

3.10

### Steps to Reproduce

Create a tag with the following type:
L2VPN Termination

Then create an L2VPN termination and include this tag. In the main list of all the l2vpn terminations add the tag column so it is visible.

Then anytime you try and view the l2vpn termination main page the server throughs an exception error

### Expected Behavior

Expect to see the l2vpn termination list without the error

### Observed Behavior

Server exception error.
<img width="997" alt="image" src="https://github.com/netbox-community/netbox/assets/26445346/9b8c9de7-16b8-44ae-acca-46e66e32f2b0">


Discussion:
Thanks for the report. Looks like the table column is being initialized with an outdated view name.

Resolving patch:
diff --git a/netbox/vpn/tables/l2vpn.py b/netbox/vpn/tables/l2vpn.py
--- a/netbox/vpn/tables/l2vpn.py
+++ b/netbox/vpn/tables/l2vpn.py
@@ -74,7 +74,7 @@ class L2VPNTerminationTable(NetBoxTable):
         verbose_name=_('Object Site')
     )
     tags = columns.TagColumn(
-        url_name='ipam:l2vpntermination_list'
+        url_name='vpn:l2vpntermination_list'
     )
 
     class Meta(NetBoxTable.Meta):


Test patch:
Repository: netbox-community/netbox

Issue:
Other VC device interfaces not showing up when bulk-editing/Edit selected
### Deployment Type

Self-hosted

### NetBox Version

v3.7.6

### Python Version

3.10

### Steps to Reproduce

1. Create a Virtual Chassis, add two or more devices, each with at least one physical interface.
2. Create LAG1 on device1, LAG2 on device2.
3. Bulk edit existing interfaces on device2 (although simply using "Edit selected" on a single interface is enough) and try to select LAG1 as LAG interface.
4. Try the same with device1/LAG2.

### Expected Behavior

No matter which particular device the interface belongs to, all LAGs show up in the dropdown menu since they're part of the same VC. And indeed that's how it works when directly editing an interface.

### Observed Behavior

Only LAG1/2 shows up when editing (an) interface(s) native to device1/2. (seems to apply to all kinds of Related Interfaces, not just LAGs)


Discussion:
Thanks for the bug report. I was able to reproduce it in the lab.
When editing a single interface, the list of candidate LAG interfaces is fetched by filtering with `virtual_chassis_member_id`, which matches all interfaces assigned to the VC. When bulk editing, the `device_id` filter is used instead; this matches only interfaces belonging to the local device. We can tweak the bulk edit form to filter by the former filter if the device is a VC member.

Resolving patch:
diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py
--- a/netbox/dcim/forms/bulk_edit.py
+++ b/netbox/dcim/forms/bulk_edit.py
@@ -1411,9 +1411,9 @@ def __init__(self, *args, **kwargs):
             device = Device.objects.filter(pk=self.initial['device']).first()
 
             # Restrict parent/bridge/LAG interface assignment by device
-            self.fields['parent'].widget.add_query_param('device_id', device.pk)
-            self.fields['bridge'].widget.add_query_param('device_id', device.pk)
-            self.fields['lag'].widget.add_query_param('device_id', device.pk)
+            self.fields['parent'].widget.add_query_param('virtual_chassis_member_id', device.pk)
+            self.fields['bridge'].widget.add_query_param('virtual_chassis_member_id', device.pk)
+            self.fields['lag'].widget.add_query_param('virtual_chassis_member_id', device.pk)
 
             # Limit VLAN choices by device
             self.fields['untagged_vlan'].widget.add_query_param('available_on_device', device.pk)


Test patch:
Repository: netbox-community/netbox

Issue:
Refactor `settings_and_registry()` context processor
### Proposed Changes

Refactor the current `settings_and_registry()` context processor into individual components which define:

- Settings
- Registry
- Configuration
- User preferences

### Justification

The functionality of the context processor has been extended over time and its name is now something of a misnomer. It might also be helpful in the future to be able to toggle these contexts individually.


Discussion:

Resolving patch:
diff --git a/netbox/netbox/context_processors.py b/netbox/netbox/context_processors.py
--- a/netbox/netbox/context_processors.py
+++ b/netbox/netbox/context_processors.py
@@ -1,18 +1,50 @@
 from django.conf import settings as django_settings
 
 from netbox.config import get_config
-from netbox.registry import registry
+from netbox.registry import registry as registry_
 
+__all__ = (
+    'config',
+    'preferences',
+    'registry',
+    'settings',
+)
 
-def settings_and_registry(request):
+
+def config(request):
     """
-    Expose Django settings and NetBox registry stores in the template context. Example: {{ settings.DEBUG }}
+    Adds NetBox configuration parameters to the template context. Example: {{ config.BANNER_LOGIN }}
     """
-    user_preferences = request.user.config if request.user.is_authenticated else {}
     return {
-        'settings': django_settings,
         'config': get_config(),
-        'registry': registry,
+    }
+
+
+def preferences(request):
+    """
+    Adds preferences for the current user (if authenticated) to the template context.
+    Example: {{ preferences|get_key:"pagination.placement" }}
+    """
+    user_preferences = request.user.config if request.user.is_authenticated else {}
+    return {
         'preferences': user_preferences,
         'htmx_navigation': user_preferences.get('ui.htmx_navigation', False) == 'true'
     }
+
+
+def registry(request):
+    """
+    Adds NetBox registry items to the template context. Example: {{ registry.models.core }}
+    """
+    return {
+        'registry': registry_,
+    }
+
+
+def settings(request):
+    """
+    Adds Django settings to the template context. Example: {{ settings.DEBUG }}
+    """
+    return {
+        'settings': django_settings,
+    }
diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py
--- a/netbox/netbox/settings.py
+++ b/netbox/netbox/settings.py
@@ -409,7 +409,10 @@ def _setting(name, default=None):
                 'django.template.context_processors.media',
                 'django.contrib.auth.context_processors.auth',
                 'django.contrib.messages.context_processors.messages',
-                'netbox.context_processors.settings_and_registry',
+                'netbox.context_processors.settings',
+                'netbox.context_processors.config',
+                'netbox.context_processors.registry',
+                'netbox.context_processors.preferences',
             ],
         },
     },


Test patch:
Repository: netbox-community/netbox

Issue:
Assign IP Address Tab missing; Only Create option exists
### Deployment Type

Self-hosted

### NetBox Version

v4.0.0

### Python Version

3.12

### Steps to Reproduce

1. Click "+" button for an interface on a given device

<img width="1226" alt="Screenshot 2024-05-06 at 17 11 04" src="https://github.com/netbox-community/netbox/assets/50723251/0b72883e-25af-4af3-9d98-5d9b709cdf45">

2. IP Address Option to "Assign IP" no longer exists since upgrading to 4.0; only the "create" option exists. 

<img width="992" alt="Screenshot 2024-05-06 at 17 10 51" src="https://github.com/netbox-community/netbox/assets/50723251/dfaa35f7-94e6-461e-ac95-728fbf0aedd7">


### Expected Behavior

A tab exists with the option to assign an existing IP address to the interface. 

### Observed Behavior

"Assign IP" Tab is missing in NetBox 4.0


Discussion:

Resolving patch:
diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py
--- a/netbox/ipam/views.py
+++ b/netbox/ipam/views.py
@@ -781,6 +781,7 @@ def get_extra_context(self, request, instance):
 class IPAddressEditView(generic.ObjectEditView):
     queryset = IPAddress.objects.all()
     form = forms.IPAddressForm
+    template_name = 'ipam/ipaddress_edit.html'
 
     def alter_object(self, obj, request, url_args, url_kwargs):
 


Test patch:
Repository: netbox-community/netbox

Issue:
Typo in IPRange model 
### Deployment Type

Self-hosted

### NetBox Version

v4.0.0

### Python Version

3.10

### Steps to Reproduce

The error message is defined as "Ending address must be **lower** than ...", but I think the correct definition is "Ending address must be **greater** than ...".
https://github.com/netbox-community/netbox/blob/195dbaed000edd7f832695b17b7a10329fbed57f/netbox/ipam/models/ip.py#L573-L579

### Expected Behavior

Ending address must be greater than the starting address ({start_address})

### Observed Behavior

Ending address must be lower than the starting address ({start_address})


Discussion:

Resolving patch:
diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py
--- a/netbox/ipam/models/ip.py
+++ b/netbox/ipam/models/ip.py
@@ -574,7 +574,7 @@ def clean(self):
             if not self.end_address > self.start_address:
                 raise ValidationError({
                     'end_address': _(
-                        "Ending address must be lower than the starting address ({start_address})"
+                        "Ending address must be greater than the starting address ({start_address})"
                     ).format(start_address=self.start_address)
                 })
 


Test patch:
Repository: netbox-community/netbox

Issue:
Unable to run scripts from CLI in v4.0
### Deployment Type

Self-hosted

### NetBox Version

v4.0.0

### Python Version

3.11

### Steps to Reproduce

1. Create a script
2. Run it with `python manage.py runscript 'module.ScriptName' inside the NetBox instance


### Expected Behavior

Script should run.

### Observed Behavior

Script fails with:
> AttributeError: 'Script' object has no attribute 'full_name'

Running the same script from GUI works fine, have tried multiple scripts, and haven't been able to run any via CLI in v4. 

Seems to be this line that fails: https://github.com/netbox-community/netbox/blob/develop/netbox/extras/management/commands/runscript.py#L104


Discussion:

Resolving patch:
diff --git a/netbox/extras/management/commands/runscript.py b/netbox/extras/management/commands/runscript.py
--- a/netbox/extras/management/commands/runscript.py
+++ b/netbox/extras/management/commands/runscript.py
@@ -85,6 +85,7 @@ def _run_script():
 
         module_name, script_name = script.split('.', 1)
         module, script = get_module_and_script(module_name, script_name)
+        script = script.python_class
 
         # Take user from command line if provided and exists, other
         if options['user']:


Test patch:
Repository: netbox-community/netbox

Issue:
Omit the django-prometheus middleware if `METRICS_ENABLED` is false
### Proposed Changes

NetBox supports the export of Prometheus metrics via [django-prometheus](https://github.com/korfuri/django-prometheus) if [configured to do so](https://docs.netbox.dev/en/stable/configuration/miscellaneous/#metrics_enabled). Metrics export is disabled by default, however the middleware is still active. This issue proposes enabling the middleware only when `METRICS_ENABLED` is true.

### Justification

We may be able to optimize performance and shrink our bug surface a bit by disabling this middleware when metrics are not in use.


Discussion:

Resolving patch:
diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py
--- a/netbox/netbox/settings.py
+++ b/netbox/netbox/settings.py
@@ -372,7 +372,6 @@ def _setting(name, default=None):
 # Middleware
 MIDDLEWARE = [
     "strawberry_django.middlewares.debug_toolbar.DebugToolbarMiddleware",
-    'django_prometheus.middleware.PrometheusBeforeMiddleware',
     'corsheaders.middleware.CorsMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.locale.LocaleMiddleware',
@@ -386,8 +385,14 @@ def _setting(name, default=None):
     'netbox.middleware.RemoteUserMiddleware',
     'netbox.middleware.CoreMiddleware',
     'netbox.middleware.MaintenanceModeMiddleware',
-    'django_prometheus.middleware.PrometheusAfterMiddleware',
 ]
+if METRICS_ENABLED:
+    # If metrics are enabled, add the before & after Prometheus middleware
+    MIDDLEWARE = [
+        'django_prometheus.middleware.PrometheusBeforeMiddleware',
+        *MIDDLEWARE,
+        'django_prometheus.middleware.PrometheusAfterMiddleware',
+    ]
 
 # URLs
 ROOT_URLCONF = 'netbox.urls'


Test patch:
Repository: netbox-community/netbox

Issue:
 The empty_text in BaseTable is not translatable because it does not utilize gettext_lazy
### Deployment Type

Self-hosted

### NetBox Version

v4.0.0

### Python Version

3.10

### Steps to Reproduce

The empty_text in BaseTable is not translatable because it does not utilize gettext_lazy.
https://github.com/netbox-community/netbox/blob/0cc2963e6f9b4f5c644201099fa9b204044653e2/netbox/netbox/tables/tables.py#L54-L55

English
![English](https://github.com/netbox-community/netbox/assets/20819471/3d6e9604-b501-4135-ae51-174721f7ea14)

Japanese
![Japanese](https://github.com/netbox-community/netbox/assets/20819471/4d80cb07-7f7c-4805-b74a-3ab579445333)

### Expected Behavior

empty_text can be translated

### Observed Behavior

empty_text cannot be translated


Discussion:

Resolving patch:
diff --git a/netbox/netbox/tables/tables.py b/netbox/netbox/tables/tables.py
--- a/netbox/netbox/tables/tables.py
+++ b/netbox/netbox/tables/tables.py
@@ -52,7 +52,7 @@ def __init__(self, *args, user=None, **kwargs):
 
         # Set default empty_text if none was provided
         if self.empty_text is None:
-            self.empty_text = f"No {self._meta.model._meta.verbose_name_plural} found"
+            self.empty_text = _("No {model_name} found").format(model_name=self._meta.model._meta.verbose_name_plural)
 
         # Determine the table columns to display by checking the following:
         #   1. User's configuration for the table


Test patch:
Repository: netbox-community/netbox

Issue:
HiddenInput form fields still show field label
### Deployment Type

Self-hosted

### NetBox Version

v4.0.0

### Python Version

3.11

### Steps to Reproduce

1. Navigate to Event rules
2. Click Add
3. Scroll to Action section of the form

### Expected Behavior

No fields that are hidden should be shown including their labels.


### Observed Behavior

There are two form labels shown that should be hidden: Action object type, Action object id


![image](https://github.com/netbox-community/netbox/assets/1256843/426e6ffe-e618-4367-8cb6-5fbd281dd0f4)



Discussion:

Resolving patch:
diff --git a/netbox/extras/forms/model_forms.py b/netbox/extras/forms/model_forms.py
--- a/netbox/extras/forms/model_forms.py
+++ b/netbox/extras/forms/model_forms.py
@@ -279,10 +279,7 @@ class EventRuleForm(NetBoxModelForm):
         FieldSet('name', 'description', 'object_types', 'enabled', 'tags', name=_('Event Rule')),
         FieldSet('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end', name=_('Events')),
         FieldSet('conditions', name=_('Conditions')),
-        FieldSet(
-            'action_type', 'action_choice', 'action_object_type', 'action_object_id', 'action_data',
-            name=_('Action')
-        ),
+        FieldSet('action_type', 'action_choice', 'action_data', name=_('Action')),
     )
 
     class Meta:


Test patch: