Skip to content

[fix] Ensure malformed UUID URLs return 404 #682#1154

Open
stktyagi wants to merge 24 commits intomasterfrom
issues/682-NoReverseMatch-error
Open

[fix] Ensure malformed UUID URLs return 404 #682#1154
stktyagi wants to merge 24 commits intomasterfrom
issues/682-NoReverseMatch-error

Conversation

@stktyagi
Copy link
Member

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Reference to Existing Issue

Closes #682

Description of Changes

Applied strict UUID regex (allowing dashless) to URL patterns, replacing permissive pattern.
Updated controller API tests to manually build invalid URLs and assert 404, resolving NoReverseMatch errors.
Added regression test to verify malformed admin URLs correctly return 404, preventing bug recurrence.

Applied strict regex across URLs and updated tests which comply while adding regression test for 404 on malformed URLs.

Fixes #682
@stktyagi stktyagi force-pushed the issues/682-NoReverseMatch-error branch from 35d7f06 to ed5eb49 Compare October 25, 2025 10:15
@stktyagi stktyagi changed the title Issues/682 no reverse match error [Fix] Ensure malformed UUID URLs return 404 #682 Oct 25, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This change replaces Django's loose regex-based URL patterns with strict UUID-based path converters across the OpenWISP controller module. Two new custom path converters are introduced: UUIDAnyConverter (accepting dashed or non-dashed UUID formats) and UUIDAnyOrFKConverter (accepting "fk" token or UUID formats). These converters are registered at app startup. The change applies to admin URL patterns, device/VPN endpoints, and WebSocket routing, replacing re_path with path and enforcing stricter validation. Additionally, several model bindings are exposed publicly in the admin module.

Sequence Diagram

[Diagram not applicable to these changes]

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description covers all required template sections with clear explanations of changes made, though documentation updates are noted as not completed.
Linked Issues check ✅ Passed The PR fully addresses issue #682 by implementing strict UUID patterns, updating tests to handle malformed URLs, and adding regression tests to prevent 500/NoReverseMatch errors.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing issue #682; new converters, path pattern updates, and test changes are all necessary and scoped to the UUID validation objective.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into master
Title check ✅ Passed The title clearly and specifically describes the main fix: ensuring malformed UUID URLs return 404 instead of raising exceptions, which directly aligns with the changeset's primary objective of replacing permissive URL patterns with strict UUID validation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch issues/682-NoReverseMatch-error

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
openwisp_controller/config/admin.py (1)

169-216: Potential 500/404 regression for __fk__ paths due to get_extra_context(object_id) assumptions.

You explicitly allow __fk__ in the strict overrides (Line 200-213), but change_view() passes object_id into get_extra_context(), which currently treats any truthy pk as a real UUID (reverse download URL + DB lookup). If /__fk__/change/ is used by UUIDAdmin/related tooling, this likely breaks.

Also, safe_urls currently drops any unnamed URL patterns (Line 175-180); safer to keep everything except the three overridden views.

Proposed fix (guard __fk__ + keep unnamed URLs)
diff --git a/openwisp_controller/config/admin.py b/openwisp_controller/config/admin.py
@@
 class BaseConfigAdmin(BaseAdmin):
@@
-    def get_extra_context(self, pk=None):
+    def get_extra_context(self, pk=None):
@@
-        if pk:
+        if pk and pk != "__fk__":
             ctx["download_url"] = reverse("{0}_download".format(prefix), args=[pk])
             try:
                 has_config = True
                 if self.model.__name__ == "Device":
                     has_config = self.model.objects.get(pk=pk)._has_config()
             except (ObjectDoesNotExist, ValidationError):
                 raise Http404()
             else:
                 if not has_config:
                     ctx["download_url"] = None
         return ctx
@@
     def get_urls(self):
@@
-        safe_urls = []
+        safe_urls = []
         for url in default_urls:
-            if url.name and not (
+            if not url.name:
+                safe_urls.append(url)
+            elif not (
                 url.name.endswith("_change")
                 or url.name.endswith("_history")
                 or url.name.endswith("_delete")
             ):
                 safe_urls.append(url)
🧹 Nitpick comments (5)
openwisp_controller/connection/channels/routing.py (1)

5-7: Good tightening of WebSocket route matching; consider de-duplicating uuid_regex.

This will prevent malformed pk segments from ever reaching the consumer (desired for the reported issue). One concern: the same regex literal is now defined in multiple modules/tests; consider centralizing it (e.g., a small openwisp_controller/utils/regex.py) to avoid future drift.

Also applies to: 13-15

openwisp_controller/config/utils.py (1)

11-13: Stricter controller URL matching looks correct; consider a shared UUID matcher/converter.

The routing change should reliably turn malformed pk URLs into 404s and keeps dashless UUID compatibility. If you want to reduce repeated regex + re_path, consider introducing a custom path converter (accept dashed + dashless) or importing a single shared regex constant.

Also applies to: 117-185

openwisp_controller/config/admin.py (1)

52-54: Minor: uuid_regex is duplicated across modules/tests—prefer a shared constant.

openwisp_controller/config/tests/test_controller.py (1)

273-279: Good: avoids reverse() for invalid pk; consider deriving from the valid reverse() result to reduce brittleness.

Instead of hardcoding "/controller/.../{pk}/", you can reverse() the valid URL and then replace/append to create the malformed path—keeps tests resilient to URL prefixing while still avoiding NoReverseMatch.

Also applies to: 338-344, 397-403, 513-519, 970-976, 1080-1092

openwisp_controller/config/tests/test_admin.py (1)

1408-1453: Nice regression coverage for “extra path segments after a valid admin URL => 404”.

Optional: consider adjusting original_bug_url construction to mirror the exact path shape from issue #682 (right now it’s valid_history_url + "history/...", i.e., “history/history/...”).

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0600954 and b764e67.

📒 Files selected for processing (6)
  • openwisp_controller/config/admin.py
  • openwisp_controller/config/tests/pytest.py
  • openwisp_controller/config/tests/test_admin.py
  • openwisp_controller/config/tests/test_controller.py
  • openwisp_controller/config/utils.py
  • openwisp_controller/connection/channels/routing.py
🧰 Additional context used
🧬 Code graph analysis (3)
openwisp_controller/connection/channels/routing.py (2)
openwisp_controller/geo/channels/routing.py (1)
  • get_routes (13-18)
openwisp_controller/routing.py (1)
  • get_routes (11-12)
openwisp_controller/config/admin.py (1)
openwisp_controller/connection/admin.py (2)
  • get_urls (61-70)
  • get_urls (164-173)
openwisp_controller/config/tests/test_controller.py (6)
openwisp_controller/config/controller/views.py (7)
  • get (147-161)
  • get (199-207)
  • get (520-526)
  • get (534-542)
  • post (217-241)
  • post (249-277)
  • post (378-457)
openwisp_controller/config/base/config.py (1)
  • key (150-155)
openwisp_controller/connection/api/views.py (1)
  • post (85-86)
openwisp_controller/config/api/views.py (2)
  • post (131-137)
  • post (144-150)
openwisp_controller/connection/connectors/ssh.py (1)
  • params (79-83)
openwisp_controller/geo/tests/test_admin_inline.py (1)
  • params (46-50)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=5.1.0
🔇 Additional comments (1)
openwisp_controller/config/tests/pytest.py (1)

16-18: Test route update is consistent with stricter UUID routing.

Also applies to: 31-35

@xoaryaa
Copy link

xoaryaa commented Jan 20, 2026

I reproduced the CI errors: NoReverseMatch is coming from the test reversing config_*_change without the admin namespace, so the URL name isn’t registered.
I can push a tiny fix using django.contrib.admin.templatetags.admin_urls.admin_urlname(...) so it resolves the correct admin:config_*_change names across Django versions.
OK if I open a follow-up PR?

@stktyagi
Copy link
Member Author

I reproduced the CI errors: NoReverseMatch is coming from the test reversing config_*_change without the admin namespace, so the URL name isn’t registered. I can push a tiny fix using django.contrib.admin.templatetags.admin_urls.admin_urlname(...) so it resolves the correct admin:config_*_change names across Django versions. OK if I open a follow-up PR?

Hey @xoaryaa, thanks for commenting,
Since those CI errors are tied to these changes, it might be better to keep everything in this PR. Maintainers can review our work at one place and so can we. Feel free to push your fix directly here

@xoaryaa
Copy link

xoaryaa commented Jan 22, 2026

Hey @stktyagi I tried pushing directly to openwisp/openwisp-controller, but I don’t have permission (403).

I’ve pushed the fix to my fork as a single commit:

  • Commit: 8b552e9409f3e63e5659080fbc3726cfe954826f
  • Branch: fix-1154-admin-urlname (repo: xoaryaa/openwisp-controller)

To bring it into this PR branch:

git remote add xoaryaa https://github.com/xoaryaa/openwisp-controller.git
git fetch xoaryaa fix-1154-admin-urlname
git cherry-pick 8b552e9409f3e63e5659080fbc3726cfe954826f

@stktyagi
Copy link
Member Author

stktyagi commented Jan 22, 2026

Hey @stktyagi I tried pushing directly to openwisp/openwisp-controller, but I don’t have permission (403).

I’ve pushed the fix to my fork as a single commit:

valid, I'll have a look and bring in your suitable changes
thank you!

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 22, 2026
@stktyagi stktyagi force-pushed the issues/682-NoReverseMatch-error branch from 9cbf862 to 1661bd1 Compare January 22, 2026 07:37
Updated the admin test suite to use robust URL resolution, fixing NoReverseMatch errors caused by hardened regex patterns.

Fixes #682
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@openwisp_controller/config/tests/test_admin.py`:
- Line 20: Remove the redundant direct import "from
openwisp_controller.config.models import Device, Template, Vpn" because the
tests call load_model() (see load_model usages) to obtain swappable models;
delete that import line so Device, Template, and Vpn resolve to the swappable
models returned by load_model() used later in the test.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9cbf862 and 1661bd1.

📒 Files selected for processing (1)
  • openwisp_controller/config/tests/test_admin.py
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2026-01-12T22:27:48.342Z
Learnt from: nemesifier
Repo: openwisp/openwisp-controller PR: 1175
File: tests/openwisp2/sample_config/migrations/0008_whoisinfo_organizationconfigsettings_whois_enabled.py:18-67
Timestamp: 2026-01-12T22:27:48.342Z
Learning: In tests/openwisp2/sample_config/models.py and corresponding test migrations, the WHOISInfo model intentionally includes an additional "details" field not present in the base AbstractWHOISInfo model. This is a testing pattern to verify that swappable models (CONFIG_WHOISINFO_MODEL) can be extended with custom fields without errors.

Applied to files:

  • openwisp_controller/config/tests/test_admin.py
📚 Learning: 2026-01-15T15:05:49.557Z
Learnt from: DragnEmperor
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/config/management/commands/clear_last_ip.py:38-42
Timestamp: 2026-01-15T15:05:49.557Z
Learning: In Django projects, when using select_related() to traverse relations (for example, select_related("organization__config_settings")), the traversed relation must not be deferred. If you also use .only() in the same query, include the relation name or FK field (e.g., "organization" or "organization_id") in the .only() list to avoid the error "Field X cannot be both deferred and traversed using select_related at the same time." Apply this guideline to Django code in openwisp_controller/config/management/commands/clear_last_ip.py and similar modules by ensuring any select_related with an accompanying only() includes the related field names to prevent deferred/traversed conflicts.

Applied to files:

  • openwisp_controller/config/tests/test_admin.py
📚 Learning: 2026-01-15T15:07:17.354Z
Learnt from: DragnEmperor
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/geo/estimated_location/tests/tests.py:172-175
Timestamp: 2026-01-15T15:07:17.354Z
Learning: In this repository, flake8 enforces E501 (line too long) via setup.cfg (max-line-length = 88) while ruff ignores E501 via ruff.toml. Therefore, use '# noqa: E501' on lines that intentionally exceed 88 characters to satisfy flake8 without affecting ruff checks. This applies to Python files across the project (any .py) and is relevant for tests as well. Use sparingly and only where breaking lines is not feasible without hurting readability or functionality.

Applied to files:

  • openwisp_controller/config/tests/test_admin.py
🧬 Code graph analysis (1)
openwisp_controller/config/tests/test_admin.py (1)
openwisp_controller/config/models.py (3)
  • Device (15-22)
  • Template (65-72)
  • Vpn (75-82)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=4.2.0
🔇 Additional comments (2)
openwisp_controller/config/tests/test_admin.py (2)

9-9: LGTM!

The admin_urlname import is correctly added and is the proper utility for dynamically generating admin URL names across Django versions.


1409-1460: LGTM!

The regression test is well-structured:

  • Uses admin_urlname for robust URL resolution across Django versions
  • Tests multiple URL patterns (change, history, original bug URL) for each model
  • Uses subTest for clear failure identification
  • Descriptive assertion messages reference issue #682 for traceability

This directly addresses the PR objective of ensuring malformed admin URLs return 404 instead of NoReverseMatch/500.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 22, 2026
Updated history URL resolution to use admin_urlname for compatibility across different admin namespaces in the CI environment.

Fixes #682
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 22, 2026
@coveralls
Copy link

coveralls commented Jan 22, 2026

Coverage Status

coverage: 98.539% (-0.07%) from 98.607%
when pulling 5828d87 on issues/682-NoReverseMatch-error
into 012a094 on master.

Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the main problem is that we are not using:
https://docs.djangoproject.com/en/5.2/topics/http/urls/#path-converters.

See below for more comments.

@xoaryaa
Copy link

xoaryaa commented Jan 23, 2026

Thanks @nemesifier im on it
Plan:

  • Add a custom uuid_any converter
  • Replace the regex re_path patterns with path converters
  • Update test_controller.py to avoid hardcoded paths

LMK if you want any changes in the above points

@xoaryaa
Copy link

xoaryaa commented Feb 2, 2026

Hey @stktyagi I have added the remaining fix (custom uuid converter + converter-based URL patterns + test updates) into one commit on my branch.

Cherry-pick:

git remote add xoaryaa https://github.com/xoaryaa/openwisp-controller.git
git fetch xoaryaa fix-1154-admin-urlname
git cherry-pick 66f3c98aaeaaedc99137505280df9212bd44377e

@xoaryaa
Copy link

xoaryaa commented Feb 3, 2026

Hi @stktyagi pls check out this new commit i made according to your suggestions
hash: cb181b5

Added custom uuid converter and converter-based URL patterns.

Fixes #682
@stktyagi stktyagi force-pushed the issues/682-NoReverseMatch-error branch from b6b312d to b860b75 Compare February 3, 2026 17:09
Updated the test to use explicit 'admin:config_device_change' instead of dynamic app_label.

Fixes #682
Used self.app_label to correctly create reversable path

Fixes #682
Restore previous test format but working and functional.

Fixes #682
Prevents WebSocket connection attempts with malformed or garbage-suffixed URLs

Fixes #682
@stktyagi
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 14, 2026
Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good @stktyagi, see my comments below.

@nemesifier nemesifier added the bug label Feb 14, 2026
@nemesifier nemesifier changed the title [Fix] Ensure malformed UUID URLs return 404 #682 [fix] Ensure malformed UUID URLs return 404 #682 Feb 14, 2026
Added docstrings to UUIDAnyConverter and UUIDAnyOrFKConverter and unit tests.

Fixes #682
coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 14, 2026
Remove unnecessary comments since docstring was added.

Fixes #682
coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 14, 2026
Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stktyagi I have a couple of comments below

if url.name and not (
url.name.endswith("_change")
or url.name.endswith("_history")
or url.name.endswith("_delete")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see these being added back below. Why is this being done, what problems does this solve?
At minimum we need an explanatory comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nemesifier
these 3 default urls which operate at the object level accept an object_id for which the default matching is rather permissive, which allowed malformed paths to be captured and routed to the view layer. This is what caused the 500 instead of returning a 404 in the first place. So to fix the two safe (non-object) urls are left unchanged and the three object-level urls are overriden using a strict uuid-compatible pattern.

Copy link
Member

@nemesifier nemesifier Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this was a real issue, we should open a bug report to Django and we should fix a lot more URLs than these. But I don't think this is a real issue.

I removed this code and brought back the original admin URLs, then changed the assertions to print:

/admin/config/device/79ffb4d7-21c7-4014-bccd-d3cbb744ce17/change/some/junk/path/here/: 302
/admin/config/device/79ffb4d7-21c7-4014-bccd-d3cbb744ce17/change/some/junk/path/here/: 302
/admin/config/device/79ffb4d7-21c7-4014-bccd-d3cbb744ce17/change/some/junk/path/here/: 301
/admin/config/template/99d44fcb-fad0-4771-8345-6a19995d85f8/change/some/junk/path/here/: 302
/admin/config/template/99d44fcb-fad0-4771-8345-6a19995d85f8/change/some/junk/path/here/: 302
/admin/config/template/99d44fcb-fad0-4771-8345-6a19995d85f8/change/some/junk/path/here/: 301
/admin/config/vpn/90f2b2fd-5de3-40dd-bea4-754a5e2b2517/change/some/junk/path/here/: 302
/admin/config/vpn/90f2b2fd-5de3-40dd-bea4-754a5e2b2517/change/some/junk/path/here/: 302
/admin/config/vpn/90f2b2fd-5de3-40dd-bea4-754a5e2b2517/change/some/junk/path/here/: 301

Status code is 302, which is fine.

The issue is specifically asking about a case in which the response is 500 internal server error, those are the case we must focus on, this issue is casued by the URLs defined by us, not Django, we shouldn't spend effort trying to fix problems that do not exist.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the reason I did these changes was because when I was manually testing that url after the minimal fix for /download it fallbacks to the same garbage url appended with /change and the same NoReverseMatch error. But you are right thats out of the scope of the bug we are trying to fix which is for /download. I'll keep the changes minimal in the next commit and post photo of what happened when I manually tested it.

stktyagi and others added 2 commits February 24, 2026 09:54
Moved local imports to the top of the file for consistency.

Fixes #682
coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 24, 2026
Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ I did some local testing. I think this patch has several issues:

  • is not properly regression testing the real bug.
  • tries to solve something which is not a bug
  • introduces a lot of unnecessary code for a simple bug fix

See my comments below.

response = self.client.get(path)
self.assertEqual(response.status_code, 404)

def test_malformed_admin_urls_return_404(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test is missing the point.

The issue is about the endpoints to download configurations, but these tests are not focusing on the main issue but on other URLs.

Please focus on replicating the bug reported in the issue description: the download URL, which affects device, template and vpn. The other admin URLs are fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll modify this test to only assert that the status code isnt 500 for the download url for device, template and vpn.

if url.name and not (
url.name.endswith("_change")
or url.name.endswith("_history")
or url.name.endswith("_delete")
Copy link
Member

@nemesifier nemesifier Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this was a real issue, we should open a bug report to Django and we should fix a lot more URLs than these. But I don't think this is a real issue.

I removed this code and brought back the original admin URLs, then changed the assertions to print:

/admin/config/device/79ffb4d7-21c7-4014-bccd-d3cbb744ce17/change/some/junk/path/here/: 302
/admin/config/device/79ffb4d7-21c7-4014-bccd-d3cbb744ce17/change/some/junk/path/here/: 302
/admin/config/device/79ffb4d7-21c7-4014-bccd-d3cbb744ce17/change/some/junk/path/here/: 301
/admin/config/template/99d44fcb-fad0-4771-8345-6a19995d85f8/change/some/junk/path/here/: 302
/admin/config/template/99d44fcb-fad0-4771-8345-6a19995d85f8/change/some/junk/path/here/: 302
/admin/config/template/99d44fcb-fad0-4771-8345-6a19995d85f8/change/some/junk/path/here/: 301
/admin/config/vpn/90f2b2fd-5de3-40dd-bea4-754a5e2b2517/change/some/junk/path/here/: 302
/admin/config/vpn/90f2b2fd-5de3-40dd-bea4-754a5e2b2517/change/some/junk/path/here/: 302
/admin/config/vpn/90f2b2fd-5de3-40dd-bea4-754a5e2b2517/change/some/junk/path/here/: 301

Status code is 302, which is fine.

The issue is specifically asking about a case in which the response is 500 internal server error, those are the case we must focus on, this issue is casued by the URLs defined by us, not Django, we shouldn't spend effort trying to fix problems that do not exist.

] + super().get_urls()
# strict overrides for the default admin views (single pattern each)
path(
"<uuid_or_fk:object_id>/history/",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hence this uuid_or_fk thing can be removed.

stktyagi and others added 2 commits February 25, 2026 19:53
Refactor the code for bug fix strictly with respect to the reported bug.

Fixes #682
@stktyagi
Copy link
Member Author

stktyagi commented Feb 25, 2026

image

tested after commit 465f19d

after latest commit
when i try for
http://localhost:8000/admin/config/device/de8fa775-1134-47b6-adc5-2da3d0626c72/history/1564/undefinedadmin/img/icon-deletelink.svg
it falls back to
http://localhost:8000/admin/config/device/de8fa775-1134-47b6-adc5-2da3d0626c72/history/1564/undefinedadmin/img/icon-deletelink.svg/change/

and then,
image

Added tests for converters in test_converters

Fixes #682
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

[bug] 500 internal server error for NoReverse match

4 participants