Skip to content

Object/multiobject required is enforced at the REST layer only, never at the model layer #719

Description

@bctiemann

Plugin Version

0.7.0

NetBox Version

4.7.1

Python Version

3.12

Steps to Reproduce

  1. Create a Custom Object Type with an object (or multiobject) field marked "Required".
  2. Create an instance directly via the ORM (e.g. model.objects.create(...)) leaving that field unset, and call full_clean() on it.
  3. Compare against a scalar field type (e.g. text) marked "Required" undergoing the same full_clean() call.

Expected Behavior

full_clean() should reject the empty value for an object/multiobject field the same way it now does for every scalar field type (fixed in #700) — "Required" should mean the same thing regardless of field type.

Observed Behavior

full_clean() accepts the empty value. ObjectFieldType.get_model_field()/MultiObjectFieldType.get_model_field() hardcode blank=True on their generated model field(s) unconditionally — never tied to field.required — so required for these two types is enforced only at the REST serializer layer (already correct, pre-#700), never at the model layer.

Raised during review of #700/#714 (h/t @jnovinger): "Object and multiobject fields still hardcode blank=True... required on those two types stays REST-only. The scalar types now enforce at both layers, which leaves the same 'Required' checkbox meaning two different things depending on field type."

Suspected Cause

Same root cause shape as #700, deliberately out of scope there (#700's own reproduction excluded these two types, since their serializer-level required handling already worked correctly before #700 — only the model-level blank was never addressed). field_types.py:932, :937 (plain object's two backing columns), and the plain multiobject field's CustomManyToManyField all hardcode blank=True regardless of field.required.

Proposed Fix

Set blank=not field.required on ObjectFieldType/MultiObjectFieldType's generated model field(s) (the non-polymorphic case's FK/M2M columns), mirroring the scalar-type fix in #700. The two polymorphic variants (GFK-backed object, PolymorphicM2MDescriptor-backed multiobject) have no real, directly-queryable backing field to attach blank to in the same way — and #700/#714's required-toggle pre-flight check (added to CustomObjectTypeField.clean()) already explicitly treats a GenericForeignKey entry and any field without a usable .blank attribute as unaffected by this, so scope this fix to the plain (non-polymorphic) case only, unless a parallel mechanism is designed for the polymorphic ones.

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions