Add GET handler to TableConfigEditView that redirects users to home with
a warning if they attempt to access the create form directly without
required object_type and table parameters from a source list view.
Fixes#22237
Introduce declarative GraphQL filter test framework with
`GraphQLFilterTest` and `GraphQLQueryTest` dataclasses. Implement
auto-filter discovery from filter class annotations with per-field-kind
test generators for string, numeric, date, range, and array lookups.
Fixes#15569
Introduce ChoiceSetField as ArrayField subclass for custom field
choices and implement choice_value lookup to filter by value element
only. Update GraphQL filter to use ExtraChoicesLookup with contains and
length options.
Fixes#22324
Repair stale `_path` references when an endpoint instance is cabled but
has no path set, as occurs during cable creation before path tracing.
The `path` accessor now refreshes the denormalized FK from the database
in this case, ensuring event payloads include connected endpoints.
Fixes#21338
* fix(ipam): Honor filters for child availability views
Retain the instantiated child FilterSet on ObjectChildrenView and expose
whether child object filters are active. Use this in IPAM child views to
avoid rendering synthetic availability rows when the child queryset has
been filtered.
This ensures Saved Filters and direct filters are respected on
Prefix IP Address, Child Prefix, Aggregate Prefix,
and VLAN Group VLAN tabs.
Fixes#22210
* refactor(ipam): Replace has_active_filters with ChildAvailabilityMixin
Extracts filter detection logic from ObjectChildrenView into a dedicated
ChildAvailabilityMixin. Compares WHERE clause signatures between
filtered and unfiltered querysets instead of inspecting filter
parameters, improving reliability when child querysets are pre-scoped
to parent objects.
ScriptFileForm only validated uploaded scripts, so a script added by
selecting a data file bypassed validate_script_content. A script that
failed to load was committed as a broken module that showed as missing
and could not be corrected, since re-adding it tripped the file path
uniqueness constraint.
Validate the data file's content in the form's clean() the same way
uploaded files are validated, so a script that cannot be loaded is
rejected before any module is created.
When no ConfigRevision exists, the empty state was never cached, so every
request re-queried core_configrevision. Distinguish a genuine cache miss from
a cached-empty state via a sentinel, seed the empty state on first load, and
only consult the database on a true miss.
Treat the cache as warm only when both 'config' and 'config_version' are
present. A missing 'config_version' (evicted or never written) now re-queries
the database instead of leaving Config.version as None when a ConfigRevision
exists. The no-revision branch writes both keys, so the intentional empty
state remains a cache hit.
The config tests shared a single Redis instance (keyed only by a static
prefix) across parallel test workers, so a no-revision test in one worker
could seed empty config/config_version keys that another worker's test then
read, causing intermittent failures. Use a per-process LocMemCache so the
shared cache keys cannot be contaminated across workers.
Add RQQueueTestMixin to centralize RQ queue cleanup for test cases that
interact with background jobs. The mixin clears all RQ queues in setUp()
and tearDown(), preventing jobs created by one test from leaking into
later unrelated test runs.
Replace duplicate queue cleanup logic in core and netbox tests with the
shared mixin for better maintainability.
Fixes#22318
Rename `CablePathTestCase` to `BaseCablePathTestCase` and
`JobRunnerTestCase` to `BaseJobRunnerTestCase` to clearly indicate
their role as abstract base classes rather than concrete test cases.
Fixes#22338
CHOICE_SETS values (IATA, ISO_3166, UN_LOCODE) are lists of (value, label)
tuples, not dicts. The .values() call introduced by #21984 treated them as
dicts, raising AttributeError: 'list' object has no attribute 'values' when
full_clean() was invoked during choice set creation.
Replace with a generator expression that extracts the first element from
each tuple, matching the same pattern used elsewhere in the same model.
Also covers the save() path when order_alphabetically=True but
extra_choices is None (base-only choice set), preventing a TypeError
when sorted() receives None.