Skip to content

All foreign keys to ContentType should use robust filtering for limit_choices_to #3892

@jeremystretch

Description

@jeremystretch

Proposed Changes

Ensure that all model fields equating to ForeignKey(to=ContentType) where limit_choices_to is in use employ robust filtering by both app and model name.

Justification

There are several models in NetBox which have one or more ForeignKey fields to ContentType and utilize limit_choices_to to constrain the available choices. In all instances where the set of ContentTypes is constrained, a concise list of (app, model) pairings should be used. For example, the Cable model currently has:

CABLE_TERMINATION_TYPES = [
    'consoleport',
    'consoleserverport',
    'interface',
    ...
]

class Cable(...):
    termination_a_type = models.ForeignKey(
        to=ContentType,
        limit_choices_to={'model__in': CABLE_TERMINATION_TYPES},
        on_delete=models.PROTECT,
        related_name='+'
    )

This is problematic, because it allows for a potential name collision across apps within NetBox. Although not currently an issue, we would do well to address this before it presents a problem.

The above instance should be changed to use the model_names_to_filter_dict() and an explicit list of (app, model) pairings to filter the field's associated queryset:

CABLE_TERMINATION_MODELS = (
    'dcim.consoleport',
    'dcim.consoleserverport',
    'dcim.interface',
    ...
)

def get_cable_termination_models():
    return model_names_to_filter_dict(CABLE_TERMINATION_MODELS)

class Cable(...):
    termination_a_type = models.ForeignKey(
        to=ContentType,
        limit_choices_to=get_cable_termination_models(),
        on_delete=models.PROTECT,
        related_name='+'
    )

This change also entails extending the model_names_to_filter_dict() function to match on both app_label and model; it currently matches only on model. A set of Q objects can be used to achieve this.

Metadata

Metadata

Assignees

Labels

status: acceptedThis issue has been accepted for implementationtype: housekeepingChanges to the application which do not directly impact the end user

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions