Skip to content

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

coderabbitai bot commented Jan 10, 2026

📝 Walkthrough

Walkthrough

Adds a module-level UUID regex constant (uuid_regex) and replaces permissive (?P<pk>[^/]+) capture groups with UUID-constraining patterns across admin URL resolution, WebSocket routing, controller URL factories, and channels routing. Tightens BaseConfigAdmin.get_urls to filter default admin URLs and enforce UUID-compatible IDs for default admin views (change, history, delete) while preserving existing custom admin paths (download, context). Introduces public model bindings via load_model for Template, Vpn, Organization, OrganizationConfigSettings, and OrganizationLimits. Adds tests asserting malformed admin URLs return 404 and updates controller tests to use explicit paths.

Sequence Diagram(s)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: fixing malformed UUID URLs to return 404 instead of errors.
Description check ✅ Passed The PR description covers the main changes, references the issue, and indicates testing and checklist items were completed, though documentation was not updated.
Linked Issues check ✅ Passed The PR successfully addresses issue #682 by implementing strict UUID regex patterns across URL patterns and adding tests to verify 404 responses for malformed URLs.
Out of Scope Changes check ✅ Passed All changes directly address the issue #682 requirements: UUID pattern validation, test updates, and regression tests for malformed admin URLs.

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

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
openwisp_controller/config/tests/test_admin.py (1)

1414-1424: Remove unused model_admin_name from test cases.

The model_admin_name variable (e.g., "config_device") is unpacked but never used in the loop body. Since admin_urlname is now used for dynamic URL resolution, this appears to be a leftover from an earlier implementation.

♻️ Proposed fix to remove unused variable
-        model_map = {"device": Device, "template": Template, "vpn": Vpn}
-        test_cases = [
-            ("device", device.pk, "config_device"),
-            ("template", template.pk, "config_template"),
-            ("vpn", vpn.pk, "config_vpn"),
-        ]
+        test_cases = [
+            ("device", device.pk, Device),
+            ("template", template.pk, Template),
+            ("vpn", vpn.pk, Vpn),
+        ]

         junk_path = "some/junk/path/here/"
         original_bug_junk = "history/1564/undefinedadmin/img/icon-deletelink.svg"

-        for model_name, valid_pk, model_admin_name in test_cases:
+        for model_name, valid_pk, model_class in test_cases:
             with self.subTest(model=model_name):
                 # CHANGE URL (robust across admin namespaces)
-                change_url_name = admin_urlname(model_map[model_name]._meta, "change")
+                change_url_name = admin_urlname(model_class._meta, "change")
                 valid_change_url = reverse(change_url_name, args=[valid_pk])
                 malformed_change_url = f"{valid_change_url}{junk_path}"

And similarly update line 1439:

                 # HISTORY URL (kept as existing explicit admin name)
-                history_url_name = admin_urlname(model_map[model_name]._meta, "history")
+                history_url_name = admin_urlname(model_class._meta, "history")
📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a96299 and 7e30f8c.

📒 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 (2)
openwisp_controller/config/tests/utils.py (4)
  • _create_device (31-44)
  • _create_template (77-87)
  • _create_vpn (130-144)
  • _create_vpn (379-386)
tests/openwisp2/sample_config/models.py (3)
  • Device (25-31)
  • Template (70-76)
  • Vpn (79-85)
🪛 Ruff (0.14.13)
openwisp_controller/config/tests/test_admin.py

1424-1424: Loop control variable model_admin_name not used within loop body

Rename unused model_admin_name to _model_admin_name

(B007)

⏰ 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.13 | django~=5.2.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.11 | 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 used in the new test method to dynamically resolve admin URL names, ensuring compatibility across different admin namespaces as mentioned in the PR discussion.


1409-1460: LGTM! Well-structured regression test for issue #682.

The test comprehensively covers:

  • Malformed change URLs for device, template, and vpn models
  • Malformed history URLs for all three models
  • The original bug URL pattern as a regression check

Good use of admin_urlname for namespace-agnostic URL resolution and subTest for organized test output.

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


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

@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

@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
@coveralls
Copy link

Coverage Status

coverage: 98.567% (-0.07%) from 98.641%
when pulling 7e30f8c on issues/682-NoReverseMatch-error
into 6697a3a 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.

[
re_path(
r"^ws/controller/device/(?P<pk>[^/]+)/$",
rf"^ws/controller/device/(?P<pk>{uuid_regex})/$",
Copy link
Member

Choose a reason for hiding this comment

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

Django has uuid path converter that we should be able to reuse here:
https://docs.djangoproject.com/en/5.2/topics/http/urls/#path-converters

I am not sure why this was added here in the first place, can't we just reuse the main url router defined in the application?

reverse("controller:device_checksum", args=[pk]), {"key": d.key}
)
bad_path = f"/controller/device/checksum/{pk}/"
response = self.client.get(bad_path, {"key": d.key})
Copy link
Member

Choose a reason for hiding this comment

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

This change is hardcoding the path instead of using reverse, which adds maintenance overhead, plus I don't understand what's the real difference with the previous version, it does not look like something we should really do.

reverse("controller:vpn_checksum", args=[pk]), {"key": v.key}
)
bad_path = f"/controller/vpn/checksum/{pk}/"
response = self.client.get(bad_path, {"key": v.key})
Copy link
Member

Choose a reason for hiding this comment

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

same here

reverse("controller:device_report_status", args=[pk]), {"key": d.key}
)
bad_path = f"/controller/device/report-status/{pk}/"
response = self.client.post(bad_path, {"key": d.key})
Copy link
Member

Choose a reason for hiding this comment

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

same here

reverse("controller:device_update_info", args=[pk]), params
)
bad_path = f"/controller/device/update-info/{pk}/"
response = self.client.post(bad_path, params)
Copy link
Member

Choose a reason for hiding this comment

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

same here

# custom app URLs
re_path(
r"^download/(?P<pk>[^/]+)/$",
rf"^download/(?P<pk>{uuid_regex})/$",
Copy link
Member

Choose a reason for hiding this comment

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

we should migrate to uuid path converters shipped in django:
https://docs.djangoproject.com/en/5.2/topics/http/urls/#path-converters

rf"^(?P<object_id>({uuid_regex}|__fk__))/change/$",
self.admin_site.admin_view(self.change_view),
name=f"{url_prefix}_change",
),
Copy link
Member

Choose a reason for hiding this comment

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

why do we really need to do this?

),
re_path(
"controller/device/report-status/(?P<pk>[^/]+)/$",
rf"controller/device/report-status/(?P<pk>{uuid_regex})/$",
Copy link
Member

Choose a reason for hiding this comment

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

same here for tha path converters

@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

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] 500 internal server error for NoReverse match

5 participants