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

Issue:
Have Docker compose invoke commands clean up after themselves
<!--
    Thank you for your interest in contributing to Nautobot! Please note
    that our contribution policy recommends that a feature request or bug
    report be opened for approval prior to filing a pull request. This
    helps avoid wasting time and effort on something that we might not
    be able to accept.

    Please indicate the relevant feature request or bug report below.
-->
# Closes: #3621
# What's Changed
<!--
    Please include:
    - A summary of the proposed changes
    - A sectioned breakdown for larger features under ## subheadings
    - Screenshots, example payloads where relevant:
      - Before/After for bugfixes
      - Using a new feature
-->
No more of this:

<img width="1492" alt="Screenshot 2023-04-19 at 17 09 50" src="https://user-images.githubusercontent.com/31187/233202124-4512f446-f726-4dbb-8aa3-702723301973.png">
<img width="1500" alt="Screenshot 2023-04-19 at 17 09 28" src="https://user-images.githubusercontent.com/31187/233202128-ea0e0e48-2fe1-4f05-839d-d33236a63131.png">


# TODO
<!--
    Please feel free to update todos to keep track of your own notes for WIP PRs.
-->
- [x] Explanation of Change(s)
- [x] Added change log fragment(s) (for more information see [the documentation](https://docs.nautobot.com/projects/core/en/stable/development/#creating-changelog-fragments))
- [x] Attached Screenshots, Payload Example
- [NA] Unit, Integration Tests
- [NA] Documentation Updates (when adding/changing features)
- [NA] Example Plugin Updates (when adding/changing features)
- [x] Outline Remaining Work, Constraints from Design



Discussion:

Resolving patch:
diff --git a/tasks.py b/tasks.py
--- a/tasks.py
+++ b/tasks.py
@@ -178,7 +178,7 @@ def run_command(context, command, **kwargs):
         if "nautobot" in results.stdout:
             compose_command = f"exec nautobot {command}"
         else:
-            compose_command = f"run --entrypoint '{command}' nautobot"
+            compose_command = f"run --rm --entrypoint '{command}' nautobot"
 
         docker_compose(context, compose_command, pty=True)
 


Test patch:
Repository: nautobot/nautobot

Issue:
2.0: AttributeError on editing user through admin
<!--
    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
* Nautobot version (Docker tag too if applicable): `next`
* Python version:
* Database platform, version:
* Middleware(s):


### Steps to Reproduce
In the Nautobot admin, navigate to a specific user to edit it.

<!-- What did you expect to happen? -->
### Expected Behavior

User edit page to load

<!-- What happened instead? -->
### Observed Behavior

```
AttributeError at /admin/users/user/9fc58549-2485-4f88-a4e5-ec4986fe644e/change/

'QuerySet' object has no attribute 'nocache'
```


Discussion:

Resolving patch:
diff --git a/nautobot/users/admin.py b/nautobot/users/admin.py
--- a/nautobot/users/admin.py
+++ b/nautobot/users/admin.py
@@ -25,7 +25,7 @@ class ObjectPermissionInline(admin.TabularInline):
     verbose_name_plural = "Permissions"
 
     def get_queryset(self, request):
-        return super().get_queryset(request).prefetch_related("objectpermission__object_types").nocache()
+        return super().get_queryset(request).prefetch_related("objectpermission__object_types")
 
     @staticmethod
     def object_types(instance):


Test patch:
Repository: nautobot/nautobot

Issue:
Cable filtering by termination type raises a KeyError
### Environment
* Nautobot version (Docker tag too if applicable): 1.5.7, `next`

<!--
    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
1. https://demo.nautobot.com/dcim/cables/?termination_a_type=dcim.interface

<!-- What did you expect to happen? -->
### Expected Behavior

Cables with an interface as the termination-a type are shown

<!-- What happened instead? -->
### Observed Behavior

![image](https://github.com/nautobot/nautobot/assets/5603551/13717972-354d-41a0-8fe6-ef9e37e7c5a0)



Discussion:
The REST API https://demo.nautobot.com/api/dcim/cables/?termination_a_type=dcim.interface works, by contrast.

Resolving patch:
diff --git a/nautobot/utilities/utils.py b/nautobot/utilities/utils.py
--- a/nautobot/utilities/utils.py
+++ b/nautobot/utilities/utils.py
@@ -910,6 +910,9 @@ def get_filterset_parameter_form_field(model, parameter, filterset=None):
         # While there are other objects using `ContentTypeMultipleChoiceFilter`, the case where
         # models that have sucha  filter and the `verbose_name_plural` has multiple words is ony one: "dynamic groups".
         plural_name = slugify_dashes_to_underscores(model._meta.verbose_name_plural)
+        # Cable-connectable models use "cable_terminations", not "cables", as the feature name
+        if plural_name == "cables":
+            plural_name == "cable_terminations"
         try:
             form_field = MultipleContentTypeField(choices_as_strings=True, feature=plural_name)
         except KeyError:


Test patch:
Repository: nautobot/nautobot

Issue:
Removing credentials from a previously synced GitRepository that requires them may result in hangs
### Environment
* Nautobot version (Docker tag too if applicable): 1.5.21

### Steps to Reproduce
1. For a Git repository that requires authentication (such as a private GitHub repository), configure the `GitRepository` in Nautobot, with appropriate credentials, mark it as providing `Jobs`, and sync it successfully (which happens in the Celery worker environment).
2. Edit the `GitRepository` to remove the credentials and resync it. The resync fails as expected (again, in the Celery worker environment.)
3. Restart the Nautobot server (during startup, the `post_upgrade` signal will trigger a check and potential sync of all Git repositories in the Nautobot server environment in order to ensure that Jobs are properly discovered).

### Expected Behavior

Nautobot server to start up, perhaps with logs indicating that the repository could not be synced.

### Observed Behavior

Nautobot server startup hangs, apparently because GitPython received and didn't handle the Git `Username:` prompt and is waiting indefinitely for user input that will never come.


Discussion:

Resolving patch:
diff --git a/nautobot/utilities/git.py b/nautobot/utilities/git.py
--- a/nautobot/utilities/git.py
+++ b/nautobot/utilities/git.py
@@ -25,6 +25,11 @@
     "X": "Unknown",
 }
 
+# Environment variables to set on appropriate `git` CLI calls
+GIT_ENVIRONMENT = {
+    "GIT_TERMINAL_PROMPT": "0",  # never prompt for user input such as credentials - important to avoid hangs!
+}
+
 
 def swap_status_initials(data):
     """Swap Git status initials with its equivalent."""
@@ -59,10 +64,12 @@ def __init__(self, path, url, clone_initially=True):
             url (str): git repo url
             clone_initially (bool): True if the repo needs to be cloned
         """
-        if os.path.isdir(path):
+        if os.path.isdir(path) and os.path.isdir(os.path.join(path, ".git")):
             self.repo = Repo(path=path)
         elif clone_initially:
-            self.repo = Repo.clone_from(url, to_path=path)
+            # Don't log `url` as it may include authentication details.
+            logger.debug("Cloning git repository to %s...", path)
+            self.repo = Repo.clone_from(url, to_path=path, env=GIT_ENVIRONMENT)
         else:
             self.repo = Repo.init(path)
             self.repo.create_remote("origin", url=url)
@@ -71,7 +78,8 @@ def __init__(self, path, url, clone_initially=True):
             self.repo.remotes.origin.set_url(url)
 
     def fetch(self):
-        self.repo.remotes.origin.fetch()
+        with self.repo.git.custom_environment(**GIT_ENVIRONMENT):
+            self.repo.remotes.origin.fetch()
 
     def checkout(self, branch, commit_hexsha=None):
         """


Test patch:
Repository: nautobot/nautobot

Issue:
2.0: Tag string representation is incorrect
### Environment
* Nautobot version (Docker tag too if applicable): `next`, e13883b7b8a4f44bca0c40d8074dcf8f82e544e6

### Steps to Reproduce
1. Create a Tag and associate it to any model
2. View the legacy-UI list view or detail view of that model

<!-- What did you expect to happen? -->
### Expected Behavior

Tag name to be displayed

<!-- What happened instead? -->
### Observed Behavior

`Tag object (<uuid>)` is displayed.

![image](https://github.com/nautobot/nautobot/assets/5603551/1da33bf8-f9ee-4fb7-b4cb-4f2c2d682496)

Appears to be a regression due to #3914.



Discussion:

Resolving patch:
diff --git a/nautobot/extras/models/tags.py b/nautobot/extras/models/tags.py
--- a/nautobot/extras/models/tags.py
+++ b/nautobot/extras/models/tags.py
@@ -46,6 +46,9 @@ class Tag(BaseModel, ChangeLoggedModel, CustomFieldModel, RelationshipModel, Not
 
     objects = BaseManager.from_queryset(TagQuerySet)()
 
+    def __str__(self):
+        return self.name
+
     class Meta:
         ordering = ["name"]
 


Test patch:
Repository: nautobot/nautobot

Issue:
Set NAUTOBOT_INSTALLATION_METRICS_ENABLED=false in the dockerfile dev stage
<!--
    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

This should propagate to all of the app dev instances since they base off of nautobot dev images. Make sure to unset this in the final stage

<!-- Provide justification for the proposed change(s). -->
### Justification

We don't want to send metrics for dev environments


Discussion:
Hey team! Please [add your planning poker estimate](https://app.zenhub.com/workspaces/Nautobot-Core-Engineering-64a875e74842500d9e80e23e/issues/nautobot/nautobot/4242?planning-poker) with Zenhub @glennmatthews @gsnider2195 @HanlinMiao @jathanism @timizuoebideri1
Is this applicable to `dev` or to `final-dev`?
@glennmatthews Probably both. App maintainers are firing off installation metrics during development.
apps generally use `final-dev` rather than `dev` which is why I asked. :-) I guess we decided not to have `DEBUG = True` disable install metrics?
> apps generally use `final-dev` rather than `dev` which is why I asked. :-) I guess we decided not to have `DEBUG = True` disable install metrics?

No, because DEBUG !== development. Would be setting the environment variable to disable for `dev` and `final-dev` be sufficient?

Resolving patch:
diff --git a/development/nautobot_config.py b/development/nautobot_config.py
--- a/development/nautobot_config.py
+++ b/development/nautobot_config.py
@@ -19,6 +19,9 @@
     # For the Docker dev environment, we don't know in advance what that IP may be, so override to skip that check
     DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda _request: DEBUG}
 
+# Do *not* send anonymized install metrics when post_upgrade or send_installation_metrics management commands are run
+INSTALLATION_METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_INSTALLATION_METRICS_ENABLED", "False"))
+
 #
 # Logging for the development environment, taking into account the redefinition of DEBUG above
 #


Test patch:
Repository: nautobot/nautobot

Issue:
Prefetch `tagged_vlans` on `InterfaceViewSet`
### As ...

Austin - Network Automation Engineer

### I want ...

The API `InterfaceViewSet` to prefetch the `tagged_vlans` (and maybe `untagged_vlan`)

### So that ...

The API is faster to return results

### I know this is done when...

The `tagged_vlans` are prefetched and the API returns results faster

### Optional - Feature groups this request pertains to.

- [X] Automation
- [ ] Circuits
- [X] DCIM
- [ ] IPAM
- [ ] Misc (including Data Sources)
- [ ] Organization
- [ ] Plugins (and other Extensibility)
- [ ] Security (Secrets, etc)
- [ ] Image Management
- [ ] UI/UX
- [ ] Documentation
- [ ] Other (not directly a platform feature)

### Database Changes

None

### External Dependencies

N/A

### Notes

Adding `.select_related("untagged_vlan").prefetch_related("tagged_vlans")` at https://github.dev/nautobot/nautobot/blob/v1.4.3/nautobot/dcim/api/views.py#L651 can reduce response time (TTFB) from 7.6 mins to 4.9 mins (36% less) with a large inventory and some interfaces with many vlans.

Maybe similar optimizations could be applied elsewhere, like [`InterfaceListView`](https://github.dev/nautobot/nautobot/blob/v1.4.3/nautobot/dcim/views.py#L1957)?


Discussion:
> Maybe similar optimizations could be applied elsewhere, like [`InterfaceListView`](https://github.dev/nautobot/nautobot/blob/v1.4.3/nautobot/dcim/views.py#L1957)?

This is already handled in https://github.com/nautobot/nautobot/blob/v1.6.1/nautobot/utilities/tables.py#L112




Resolving patch:
diff --git a/nautobot/dcim/api/views.py b/nautobot/dcim/api/views.py
--- a/nautobot/dcim/api/views.py
+++ b/nautobot/dcim/api/views.py
@@ -573,7 +573,8 @@ class InterfaceViewSet(PathEndpointMixin, NautobotModelViewSet):
         "lag",
         "status",
         "cable",
-    ).prefetch_related("tags", "_path__destination", "_cable_peer", "ip_addresses")
+        "untagged_vlan",
+    ).prefetch_related("tags", "_path__destination", "_cable_peer", "ip_addresses", "tagged_vlans")
     serializer_class = serializers.InterfaceSerializer
     filterset_class = filters.InterfaceFilterSet
 
diff --git a/nautobot/virtualization/api/views.py b/nautobot/virtualization/api/views.py
--- a/nautobot/virtualization/api/views.py
+++ b/nautobot/virtualization/api/views.py
@@ -83,6 +83,7 @@ class VMInterfaceViewSet(ModelViewSet, NotesViewSetMixin):
         "parent_interface",
         "bridge",
         "status",
-    ).prefetch_related("tags", "tagged_vlans")
+        "untagged_vlan",
+    ).prefetch_related("tags", "ip_addresses", "tagged_vlans")
     serializer_class = serializers.VMInterfaceSerializer
     filterset_class = filters.VMInterfaceFilterSet


Test patch:
Repository: nautobot/nautobot

Issue:
Expose django slugify in jinja filters
As a Network Automation Engineer, I want the django slugify utility function to be exposed for use in Nautobot jinija2 templates, so that I can have feature parity with the fact it is already exposed as a django template filter.


I will know this is complete when the django slugify function is exposed a registered jinja2 filter.


Discussion:
Hey team! Please [add your planning poker estimate](https://app.zenhub.com/workspaces/Nautobot-Core-Product-64a8783b7a3f4b1225973a0c/issues/nautobot/nautobot/4477?planning-poker) with Zenhub @glennmatthews @gsnider2195 @HanlinMiao @jathanism @timizuoebideri1

Resolving patch:
diff --git a/nautobot/core/templatetags/helpers.py b/nautobot/core/templatetags/helpers.py
--- a/nautobot/core/templatetags/helpers.py
+++ b/nautobot/core/templatetags/helpers.py
@@ -9,6 +9,7 @@
 from django.templatetags.static import StaticNode, static
 from django.urls import NoReverseMatch, reverse
 from django.utils.html import format_html, strip_tags
+from django.utils.text import slugify as django_slugify
 from django.utils.safestring import mark_safe
 from django_jinja import library
 from markdown import markdown
@@ -522,6 +523,12 @@ def quote_string(value):
     return value
 
 
+@library.filter()
+def slugify(value):
+    """Return a slugified version of the value."""
+    return django_slugify(value)
+
+
 #
 # Tags
 #


Test patch:
diff --git a/nautobot/core/tests/test_jinja_filters.py b/nautobot/core/tests/test_jinja_filters.py
--- a/nautobot/core/tests/test_jinja_filters.py
+++ b/nautobot/core/tests/test_jinja_filters.py
@@ -43,6 +43,7 @@ def test_templatetags_helpers_in_jinja(self):
             "meters_to_feet",
             "get_item",
             "settings_or_config",
+            "slugify",
         ]
 
         # For each helper, try to render a jinja template with render_jinja2 and fail if TemplateAssertionError is raised
Repository: nautobot/nautobot

Issue:
Job Results filter only allowing exact date matches 
### Environment
* Nautobot version: 1.6, 2.0.3
* Python version: Any
* Database platform, version: Any

### Steps to Reproduce
1. Navigate to Job Results
2. Select Filter
3. Click Advanced
4. Select Field Created or Completed
5. Lookup type is only "exact"

### Expected Behavior
Job Results should be filterable by any date matches, including less than, greater than, etc.

### Observed Behavior
You can only match the date for Created and Completed by the exact time, down to the nanosecond with TZ offset (ie date_created = "2023-09-21T19:52:33.769869+00:00")

This has already been confirmed to be an issue with the JobResultFilterSet explicitly defining the DateTimeFilter value instead of the default value of MultiValueDateTimeFilter


Discussion:

Resolving patch:
diff --git a/nautobot/extras/filters/__init__.py b/nautobot/extras/filters/__init__.py
--- a/nautobot/extras/filters/__init__.py
+++ b/nautobot/extras/filters/__init__.py
@@ -633,8 +633,6 @@ class JobResultFilterSet(BaseFilterSet, CustomFieldModelFilterSetMixin):
         queryset=Job.objects.all(),
         label="Job (ID) - Deprecated (use job_model filter)",
     )
-    date_created = django_filters.DateTimeFilter()
-    date_done = django_filters.DateTimeFilter()
     status = django_filters.MultipleChoiceFilter(choices=JobResultStatusChoices, null_value=None)
 
     class Meta:
@@ -674,12 +672,9 @@ class ScheduledJobFilterSet(BaseFilterSet):
         label="Job (ID) - Deprecated (use job_model filter)",
     )
 
-    first_run = django_filters.DateTimeFilter()
-    last_run = django_filters.DateTimeFilter()
-
     class Meta:
         model = ScheduledJob
-        fields = ["id", "name", "total_run_count"]
+        fields = ["id", "name", "total_run_count", "start_time", "last_run_at"]
 
 
 #


Test patch:
Repository: nautobot/nautobot

Issue:
Job Results filter only allowing exact date matches 
### Environment
* Nautobot version: 1.6, 2.0.3
* Python version: Any
* Database platform, version: Any

### Steps to Reproduce
1. Navigate to Job Results
2. Select Filter
3. Click Advanced
4. Select Field Created or Completed
5. Lookup type is only "exact"

### Expected Behavior
Job Results should be filterable by any date matches, including less than, greater than, etc.

### Observed Behavior
You can only match the date for Created and Completed by the exact time, down to the nanosecond with TZ offset (ie date_created = "2023-09-21T19:52:33.769869+00:00")

This has already been confirmed to be an issue with the JobResultFilterSet explicitly defining the DateTimeFilter value instead of the default value of MultiValueDateTimeFilter


Discussion:

Resolving patch:
diff --git a/nautobot/extras/filters/__init__.py b/nautobot/extras/filters/__init__.py
--- a/nautobot/extras/filters/__init__.py
+++ b/nautobot/extras/filters/__init__.py
@@ -661,8 +661,6 @@ class JobResultFilterSet(BaseFilterSet, CustomFieldModelFilterSetMixin):
         label="Job (ID) - Deprecated (use job_model filter)",
     )
     obj_type = ContentTypeFilter()
-    created = django_filters.DateTimeFilter()
-    completed = django_filters.DateTimeFilter()
     status = django_filters.MultipleChoiceFilter(choices=JobResultStatusChoices, null_value=None)
 
     class Meta:
@@ -702,12 +700,9 @@ class ScheduledJobFilterSet(BaseFilterSet):
         label="Job (ID) - Deprecated (use job_model filter)",
     )
 
-    first_run = django_filters.DateTimeFilter()
-    last_run = django_filters.DateTimeFilter()
-
     class Meta:
         model = ScheduledJob
-        fields = ["id", "name", "total_run_count"]
+        fields = ["id", "name", "total_run_count", "start_time", "last_run_at"]
 
 
 #


Test patch:
Repository: nautobot/nautobot

Issue:
Computed fields not return by GraphQL query
### Environment
* Nautobot version (Docker tag too if applicable): 2.0.3
* Python version: 3.10.12
* Database platform, version: postgres, 14.9
* Middleware(s):

<!--
Having issues accessing computed_fields in version 2.0.3. Computed fields are visible in the UI however, GraphQL query (from UI) throws the following message “CustomFieldModel.get_computed_field() got an unexpected keyword argument ‘slug’”
Query:
{
  devices{
    name
    cpf_olt_name
  }
}
Have stop/started Nautobot and rebooted the system. This was working prior to upgrading from 1.5. Has anyone else seen this? Was told to submit a bug by Glenn M in the Nautobot Slack channel.
-->

### Steps to Reproduce
1. Upgraded from Nautobot 1.5. to 2.0.3
2. Created new computed field
{% if obj.type == "xgs-pon" %}
olt-{{ obj.mac_address }}
{% endif %}
4. Attempted GraphQL for new and pre-upgrade computed fields from the web interface and with pynautobot. 

<!-- What did you expect to happen? -->
Computed field key:value is returned


<!-- What happened instead? -->
Received this error after a query from the web interface:
“CustomFieldModel.get_computed_field() got an unexpected keyword argument ‘slug’”



Discussion:
Tested on a fresh install of v2.0.4. Get the same error message.
Confirmed, incorrect code is [here](https://github.com/nautobot/nautobot/blob/develop/nautobot/core/graphql/generators.py#L119).

Resolving patch:
diff --git a/nautobot/core/graphql/generators.py b/nautobot/core/graphql/generators.py
--- a/nautobot/core/graphql/generators.py
+++ b/nautobot/core/graphql/generators.py
@@ -116,7 +116,7 @@ def generate_computed_field_resolver(name, resolver_name):
     """
 
     def resolve_computed_field(self, info, **kwargs):
-        return self.get_computed_field(slug=name)
+        return self.get_computed_field(key=name)
 
     resolve_computed_field.__name__ = resolver_name
     return resolve_computed_field


Test patch: