-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
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.