Repository: netbox-community/netbox
Pull request: Fixes return_url for image attachment
<!--
    Thank you for your interest in contributing to NetBox! Please note that
    our contribution policy requires that a feature request or bug report be
    approved and assigned prior to opening a pull request. This helps avoid
    waste time and effort on a proposed change that we might not be able to
    accept.

    IF YOUR PULL REQUEST DOES NOT REFERENCE AN ISSUE WHICH HAS BEEN ASSIGNED
    TO YOU, IT WILL BE CLOSED AUTOMATICALLY.

    Please specify your assigned issue number on the line below.
-->
### Fixes: #12538

<!--
    Please include a summary of the proposed changes below.
-->
I have added support for parsing `return_url` from the request in the table if it exists. The old functionality is still retained if the parameter is not provided. I could not find any other clean way of redirecting the user back to where the request was initiated.

Problem statement:
Delete image attachment on device (type) should return to device not to image attachments list
### NetBox version

v3.5.1

### Feature type

Change to existing functionality

### Proposed functionality

When deleting an attached image (picture) from a detail view of a device or device type you should return to the device / device type from which you started this.
A.t.m. you are coming to the list of image attachments and need to navigate back to the device.

### Use case

Usability improvement as it is most likely that you are in the context of a specific device / device type you are maintaining and not the list of all image attachments.

### Database changes

_No response_

### External dependencies

_No response_

Hints from issue discussion:

Commit message: fixes return_url for image attachment #12538

Patch to review:
diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py
index 66ee787a8fa..ed8c37cc214 100644
--- a/netbox/netbox/tables/columns.py
+++ b/netbox/netbox/tables/columns.py
@@ -235,7 +235,12 @@ def render(self, record, table, **kwargs):
 
         model = table.Meta.model
         request = getattr(table, 'context', {}).get('request')
-        url_appendix = f'?return_url={quote(request.get_full_path())}' if request else ''
+        query_params = request.GET.copy() if request else {}
+        if return_url := query_params.pop('return_url', None):
+            url_appendix = f'?return_url={quote(return_url[0])}'
+        else:
+            url_appendix = f'?return_url={quote(request.get_full_path())}' if request else ''
+
         html = ''
 
         # Compile actions menu
diff --git a/netbox/templates/inc/panels/image_attachments.html b/netbox/templates/inc/panels/image_attachments.html
index 0c1d212d93b..463b6716b42 100644
--- a/netbox/templates/inc/panels/image_attachments.html
+++ b/netbox/templates/inc/panels/image_attachments.html
@@ -5,7 +5,7 @@ <h5 class="card-header">
     Images
   </h5>
   <div class="card-body htmx-container table-responsive"
-  hx-get="{% url 'extras:imageattachment_list' %}?content_type_id={{ object|content_type_id }}&object_id={{ object.pk }}"
+  hx-get="{% url 'extras:imageattachment_list' %}?content_type_id={{ object|content_type_id }}&object_id={{ object.pk }}&return_url={{ request.path }}"
   hx-trigger="load"></div>
   {% if perms.extras.add_imageattachment %}
     <div class="card-footer text-end noprint">


Code review comments:
diff_hunk: @@ -235,7 +235,12 @@ def render(self, record, table, **kwargs):
 
         model = table.Meta.model
         request = getattr(table, 'context', {}).get('request')
-        url_appendix = f'?return_url={quote(request.get_full_path())}' if request else ''
+        query_params = request.GET.copy() if request else {}
+        if return_url := query_params.pop('return_url', None):
path: netbox/netbox/tables/columns.py
text: @user1:
I could be missing something but this would this not be sufficient?

```suggestion
        if return_url := request.GET.get('return_url'):
```

@user1:
We can probably simplify this to something like:

```python
return_url = request.GET.get('return_url', request.get_full_path())
url_appendix = f'?return_url={quote(return_url)}' if return_url else ''
```

@author:
> I could be missing something but this would this not be sufficient?

I tested this using services on device and that worked just it was before. Then did the same test using image attachment and post edit and delete, I landed up on the device page.

While implementing this, I was thinking the same solution should be implemented application wide though.

If you can think of a use-case, that I ay have missed let know.

@user1:
I've introduced the `htmx_table` template tag as a utility for consistently embedding HTMX tables in this manner. As employing its use beyond image attachments is outside the scope of this issue, I'm going to consider this fixed, and open a separate issue to track its further adoption.