Skip to content

22378 reshape customscript object column#22574

Open
mburggraf wants to merge 3 commits into
netbox-community:mainfrom
mburggraf:22378-reshape-customscript-object-column
Open

22378 reshape customscript object column#22574
mburggraf wants to merge 3 commits into
netbox-community:mainfrom
mburggraf:22378-reshape-customscript-object-column

Conversation

@mburggraf

Copy link
Copy Markdown
Contributor

Closes: #22378

I went for a simple approach, using parent_object when present. I was thinking about doing the same for .device and .group, but wasn't convinced it would help much.

I was wondering, if there is some sort of convention on how a parent object should be referred to (see discussion #22403).

Removed the unused render_url() function as well.

@jeremystretch jeremystretch self-requested a review June 30, 2026 16:56
@jeremystretch

Copy link
Copy Markdown
Member

@claude /review Only report on issues of potential concern; we don't need commentary on anything that doesn't require further consideration.

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Claude finished @jeremystretch's task in 58s —— View job


Review

One critical bug and one performance concern to address.


RuntimeException is not a Python exception (tables.py:837)

except RuntimeException:

RuntimeException is a Java class — it doesn't exist in Python. Because Python only evaluates the except clause when an exception is actually raised, this silently works when no exception occurs. But when any exception is raised inside the try block (e.g. Resolver404, ObjectDoesNotExist, AttributeError from a non-standard view), Python will attempt to look up RuntimeException, find it undefined, and raise a NameError — the opposite of the intended fallback behavior.

Fix: use Exception to catch everything, or narrow to the specific exceptions that might occur (Resolver404, model.DoesNotExist, AttributeError). Fix this →


Per-row database query (tables.py:827)

obj = model.objects.get(**match.kwargs)

This issues a separate database query for every row in the log table. Scripts that log many objects will produce a large number of queries per page render. Since ScriptResultsTable already has record['url'] and the display value, consider whether the parent object info could be injected into the log record at write time (when the script runs) instead of being resolved on every render.


  • Read changed files and analyze the PR
  • Post review feedback

@jeremystretch jeremystretch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I appreciate what you're trying to achieve with this change, but I'm not sure it' feasible from a performance standpoint.

Comment thread netbox/extras/tables/tables.py Outdated
record['url'],
value,
)
except RuntimeException:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is an invalid exception, but it also doesn't adequately contain a potential failure. The method will still attempt to reference record['url'], which (per line 820) might not exist.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

My intention was, that if anything goes wrong, the whole function would execute in the same way, it does currently, before my PR.
So if record['url'] is empty, it currently generates a link with empty href
I fixed the Exception name.
But I noticed, that the if statement is kinda useless if I accept running into an exception anyways, so I removed the if-line for performance reasons.

Comment thread netbox/extras/tables/tables.py Outdated
Comment thread netbox/extras/tables/tables.py Outdated
if not (hasattr(view_class, "queryset") and hasattr(view_class.queryset, "model")):
return format_html("<a href='{}'>{}</a>", record['url'], value)
model = view_class.queryset.model
obj = model.objects.get(**match.kwargs)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We need to avoid potentially triggering an individual query per log line.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Actually I wanted to go with a change, which has as minimal impact on the current structures as possible.

The suggestion from Claude to injected the parent object information into the log record at write time would go against this, since it would impact the whole log format and therefore breaking backwards compatibility. (Scripts which were run before the change don't possess this information)

The additional query is only done for those log lines, who have set an object in the first place (since render_object() isn't even called when there is no object), therefore IMHO the trade-off regarding the performance does not weigh as heavily in comparison.

- RepairException Name
- Move include to top
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.

Reshape object column for custom script log view

2 participants