nautobot.apps.utils
¶
Nautobot utility functions.
nautobot.apps.utils.ChangeLoggedModelsQuery
¶
Bases: FeaturedQueryMixin
Helper class to get ContentType for models that implements the to_objectchange method for change logging.
list_subclasses()
¶
Return a list of classes that implement the to_objectchange method
nautobot.apps.utils.FeatureQuery
¶
Helper class that delays evaluation of the registry contents for the functionality store until it has been populated.
as_dict()
¶
Given an extras feature, return a dict of app_label: [models] for content type lookup
get_choices()
¶
Given an extras feature, return a list of 2-tuple of (model_label, pk)
suitable for use as choices
on a choice field:
>>> FeatureQuery('statuses').get_choices()
[('dcim.device', 13), ('dcim.rack', 34)]
get_query()
¶
Given an extras feature, return a Q object for content type lookup
list_subclasses()
¶
Return a list of model classes that declare this feature.
nautobot.apps.utils.FeaturedQueryMixin
¶
nautobot.apps.utils.GitRepo
¶
head
property
¶
Current checked out repository head commit.
__init__(path, url, clone_initially=True)
¶
Ensure that we have a clone of the given remote Git repository URL at the given local directory path.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path |
str
|
path to git repo |
required |
url |
str
|
git repo url |
required |
clone_initially |
bool
|
True if the repo needs to be cloned |
True
|
checkout(branch, commit_hexsha=None)
¶
Check out the given branch, and optionally the specified commit within that branch.
Returns:
Type | Description |
---|---|
(str, bool)
|
commit_hexsha the repo contains now, whether any change occurred |
nautobot.apps.utils.RoleModelsQuery
¶
Bases: FeaturedQueryMixin
Helper class to get ContentType models that implements role.
list_subclasses()
¶
Return a list of classes that implements roles e.g roles = ...
nautobot.apps.utils.TaggableClassesQuery
¶
Bases: FeaturedQueryMixin
Helper class to get ContentType models that implements tags(TagsField)
list_subclasses()
¶
Return a list of classes that has implements tags e.g tags = TagsField(...)
nautobot.apps.utils.build_lookup_label(field_name, _verbose_name)
¶
Return lookup expr with its verbose name
Parameters:
Name | Type | Description | Default |
---|---|---|---|
field_name |
str
|
Field name e.g name__iew |
required |
_verbose_name |
str
|
The verbose name for the lookup expr which is suffixed to the field name e.g iew -> iendswith |
required |
Examples:
nautobot.apps.utils.check_if_key_is_graphql_safe(model_name, key, field_name='key')
¶
Helper method to check if a key field is Python/GraphQL safe. Used in CustomField, ComputedField and Relationship models.
nautobot.apps.utils.class_deprecated(message)
¶
Decorator to mark a class as deprecated with a custom message about what to do instead of subclassing it.
nautobot.apps.utils.class_deprecated_in_favor_of(replacement_class)
¶
Decorator to mark a class as deprecated and suggest a replacement class if it is subclassed from.
nautobot.apps.utils.convert_git_diff_log_to_list(logs)
¶
Convert Git diff log into a list splitted by \n
Example:
>>> git_log = "M index.html
R sample.txt" >>> print(convert_git_diff_log_to_list(git_log)) ["Modification - index.html", "Renaming - sample.txt"]
nautobot.apps.utils.convert_querydict_to_factory_formset_acceptable_querydict(request_querydict, filterset)
¶
Convert request QueryDict/GET into an acceptable factory formset QueryDict
while discarding querydict
params which are not part of filterset_class
params
Parameters:
Name | Type | Description | Default |
---|---|---|---|
request_querydict |
QueryDict
|
QueryDict to convert |
required |
filterset |
FilterSet
|
Filterset class |
required |
Examples:
>>> convert_querydict_to_factory_formset_acceptable_querydict({"status": ["active", "decommissioning"], "name__ic": ["location"]},)
>>> {
... 'form-TOTAL_FORMS': [3],
... 'form-INITIAL_FORMS': ['0'],
... 'form-MIN_NUM_FORMS': [''],
... 'form-MAX_NUM_FORMS': [''],
... 'form-0-lookup_field': ['status'],
... 'form-0-lookup_type': ['status'],
... 'form-0-value': ['active', 'decommissioning'],
... 'form-1-lookup_field': ['name'],
... 'form-1-lookup_type': ['name__ic'],
... 'form-1-value': ['location']
... }
nautobot.apps.utils.custom_validator_clean(model_clean_func)
¶
Decorator that wraps a models existing clean method to also execute registered plugin custom validators
:param model_clean_func: The original model clean method which is to be wrapped
nautobot.apps.utils.deepmerge(original, new)
¶
Deep merge two dictionaries (new into original) and return a new dict
nautobot.apps.utils.ensure_content_type_and_field_name_in_query_params(query_params)
¶
Ensure query_params
includes content_type
and field_name
and content_type
is a valid ContentType.
Return the 'ContentTypes' model and 'field_name' if validation was successful.
nautobot.apps.utils.fixup_null_statuses(*, model, model_contenttype, status_model)
¶
For instances of model that have an invalid NULL status field, create and use a special status_model instance.
nautobot.apps.utils.flatten_dict(d, prefix='', separator='.')
¶
Flatten nested dictionaries into a single level by joining key names with a separator.
:param d: The dictionary to be flattened :param prefix: Initial prefix (if any) :param separator: The character to use when concatenating key names
nautobot.apps.utils.flatten_iterable(iterable)
¶
Flatten a nested iterable such as a list of lists, keeping strings intact.
:param iterable: The iterable to be flattened :returns: generator
nautobot.apps.utils.foreground_color(bg_color)
¶
Return the ideal foreground color (black or white) for a given background color in hexadecimal RGB format.
nautobot.apps.utils.generate_signature(request_body, secret)
¶
Return a cryptographic signature that can be used to verify the authenticity of webhook data.
nautobot.apps.utils.get_all_lookup_expr_for_field(model, field_name)
¶
Return all lookup expressions for field_name
in model
filterset
nautobot.apps.utils.get_all_new_ui_ready_routes()
¶
nautobot.apps.utils.get_base_template(base_template, model)
¶
Returns the name of the base template, if the base_template is not None
Otherwise, default to using "NautobotUIViewSet
exists.
If both templates do not exist, fall back to "base.html".
nautobot.apps.utils.get_celery_queues()
¶
Return a dictionary of celery queues and the number of workers active on the queue in the form {queue_name: num_workers}
nautobot.apps.utils.get_changes_for_model(model)
¶
Return a queryset of ObjectChanges for a model or instance. The queryset will be filtered by the model class. If an instance is provided, the queryset will also be filtered by the instance id.
nautobot.apps.utils.get_filter_field_label(filter_field)
¶
Return a label for a given field name and value.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
filter_field |
Filter
|
The filter to get a label for |
required |
Returns:
Type | Description |
---|---|
str
|
The label for the given field |
nautobot.apps.utils.get_filterable_params_from_filter_params(filter_params, non_filter_params, filterset)
¶
Remove any non_filter_params
and fields that are not a part of the filterset from filter_params
to return only queryset filterable parameters.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
filter_params |
QueryDict
|
Filter param querydict |
required |
non_filter_params |
list
|
Non queryset filterable params |
required |
filterset |
FilterSet
|
The FilterSet class |
required |
Returns:
Type | Description |
---|---|
QueryDict
|
Filter param querydict with only queryset filterable params |
nautobot.apps.utils.get_filterset_for_model(model)
¶
Return the FilterSet
class associated with a given model
.
The FilterSet
class is expected to be in the filters
module within the application
associated with the model and its name is expected to be {ModelName}FilterSet
.
If a matching FilterSet
is not found, this will return None
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model |
BaseModel
|
A model class |
required |
Returns:
Type | Description |
---|---|
Union[FilterSet, None]
|
Either the |
nautobot.apps.utils.get_filterset_parameter_form_field(model, parameter, filterset=None)
¶
Return the relevant form field instance for a filterset parameter e.g DynamicModelMultipleChoiceField, forms.IntegerField e.t.c
nautobot.apps.utils.get_form_for_model(model, form_prefix='')
¶
Return the Form
class associated with a given model
.
The Form
class is expected to be in the forms
module within the application
associated with the model and its name is expected to be {ModelName}{form_prefix}Form
.
If a matching Form
is not found, this will return None
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
form_prefix |
str
|
An additional prefix for the form name (e.g. |
''
|
Returns:
Type | Description |
---|---|
Union[Form, None]
|
Either the |
nautobot.apps.utils.get_latest_release(pre_releases=False)
¶
Get latest known Nautobot release from cache, or if not available, queue up a background task to populate the cache.
Returns:
Type | Description |
---|---|
(Version, str)
|
Latest release version and the release URL, if found in the cache |
(unknown, None)
|
If not present in the cache at this time |
nautobot.apps.utils.get_model_from_name(model_name)
¶
Given a full model name in dotted format (example: dcim.model
), a model class is returned if valid.
:param model_name: Full dotted name for a model as a string (ex: dcim.model
)
:type model_name: str
:raises TypeError: If given model name is not found.
:return: Found model.
nautobot.apps.utils.get_only_new_ui_ready_routes(patterns, prefix='')
¶
Recursively traverses Django URL patterns to find routes associated with view classes
that have the use_new_ui
attribute set to True
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
patterns |
list
|
List of URL patterns to traverse. |
required |
prefix |
str
|
URL pattern prefix to include when constructing route patterns. |
''
|
Returns:
Type | Description |
---|---|
list
|
A list of route patterns associated with view classes that use the new UI. |
nautobot.apps.utils.get_permission_for_model(model, action)
¶
Resolve the named permission for a given model (or instance) and action (e.g. view or add).
:param model: A model or instance :param action: View, add, change, or delete (string)
nautobot.apps.utils.get_related_class_for_model(model, module_name, object_suffix)
¶
Return the appropriate class associated with a given model matching the module_name
and
object_suffix
.
The given model
can either be a model class, a model instance, or a dotted representation (ex: dcim.device
).
The object class is expected to be in the module within the application
associated with the model and its name is expected to be {ModelName}{object_suffix}
.
If a matching class is not found, this will return None
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model |
Union[BaseModel, str]
|
A model class, instance, or dotted representation |
required |
module_name |
str
|
The name of the module to search for the object class |
required |
object_suffix |
str
|
The suffix to append to the model name to find the object class |
required |
Returns:
Type | Description |
---|---|
Union[BaseModel, str]
|
Either the matching object class or None |
nautobot.apps.utils.get_route_for_model(model, action, api=False)
¶
Return the URL route name for the given model and action. Does not perform any validation. Supports both core and App routes.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model |
(Model, str)
|
Class, Instance, or dotted string of a Django Model |
required |
action |
str
|
name of the action in the route |
required |
api |
bool
|
If set, return an API route. |
False
|
Returns:
Type | Description |
---|---|
str
|
return the name of the view for the model/action provided. |
Examples:
>>> get_route_for_model(Device, "list")
"dcim:device_list"
>>> get_route_for_model(Device, "list", api=True)
"dcim-api:device-list"
>>> get_route_for_model("dcim.location", "list")
"dcim:location_list"
>>> get_route_for_model("dcim.location", "list", api=True)
"dcim-api:location-list"
>>> get_route_for_model(ExampleModel, "list")
"plugins:example_app:examplemodel_list"
>>> get_route_for_model(ExampleModel, "list", api=True)
"plugins-api:example_app-api:examplemodel-list"
nautobot.apps.utils.get_settings_or_config(variable_name)
¶
Get a value from Django settings (if specified there) or Constance configuration (otherwise).
nautobot.apps.utils.get_table_for_model(model)
¶
Return the Table
class associated with a given model
.
The Table
class is expected to be in the tables
module within the application
associated with the model and its name is expected to be {ModelName}Table
.
If a matching Table
is not found, this will return None
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model |
BaseModel
|
A model class |
required |
Returns:
Type | Description |
---|---|
Union[Table, None]
|
Either the |
nautobot.apps.utils.get_url_for_url_pattern(url_pattern)
¶
Given a URL pattern, construct a URL string that would match that pattern.
Examples:
>>> get_url_for_url_pattern("/plugins/example-app/^models/(?P<pk>[^/.]+)/$")
'/plugins/example-app/models/00000000-0000-0000-0000-000000000000/'
>>> get_url_for_url_pattern("/circuits/circuit-terminations/<uuid:termination_a_id>/connect/<str:termination_b_type>/")
'/circuits/circuit-terminations/00000000-0000-0000-0000-000000000000/connect/string/'
nautobot.apps.utils.get_url_patterns(urlconf=None, patterns_list=None, base_path='/')
¶
Recursively yield a list of registered URL patterns.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
urlconf |
URLConf
|
Python module such as |
None
|
patterns_list |
list
|
Used in recursion. Generally can be omitted on initial call.
Default if unspecified is the |
None
|
base_path |
str
|
String to prepend to all URL patterns yielded.
Default if unspecified is the string |
'/'
|
Yields:
Type | Description |
---|---|
str
|
Each URL pattern defined in the given urlconf and its descendants |
Examples:
>>> generator = get_url_patterns()
>>> next(generator)
'/'
>>> next(generator)
'/search/'
>>> next(generator)
'/login/'
>>> next(generator)
'/logout/'
>>> next(generator)
'/circuits/circuits/<uuid:pk>/terminations/swap/'
>>> import example_plugin.urls as example_urls
>>> for url_pattern in get_url_patterns(example_urls, base_path="/plugins/example-app/"):
... print(url_pattern)
...
/plugins/example-app/
/plugins/example-app/config/
/plugins/example-app/models/<uuid:pk>/dynamic-groups/
/plugins/example-app/other-models/<uuid:pk>/dynamic-groups/
/plugins/example-app/docs/
/plugins/example-app/circuits/<uuid:pk>/example-app-tab/
/plugins/example-app/devices/<uuid:pk>/example-app-tab-1/
/plugins/example-app/devices/<uuid:pk>/example-app-tab-2/
/plugins/example-app/override-target/
/plugins/example-app/^models/$
/plugins/example-app/^models/add/$
/plugins/example-app/^models/import/$
/plugins/example-app/^models/edit/$
/plugins/example-app/^models/delete/$
/plugins/example-app/^models/all-names/$
/plugins/example-app/^models/(?P<pk>[^/.]+)/$
/plugins/example-app/^models/(?P<pk>[^/.]+)/delete/$
/plugins/example-app/^models/(?P<pk>[^/.]+)/edit/$
/plugins/example-app/^models/(?P<pk>[^/.]+)/changelog/$
/plugins/example-app/^models/(?P<pk>[^/.]+)/notes/$
/plugins/example-app/^other-models/$
/plugins/example-app/^other-models/add/$
/plugins/example-app/^other-models/edit/$
/plugins/example-app/^other-models/delete/$
/plugins/example-app/^other-models/(?P<pk>[^/.]+)/$
/plugins/example-app/^other-models/(?P<pk>[^/.]+)/delete/$
/plugins/example-app/^other-models/(?P<pk>[^/.]+)/edit/$
/plugins/example-app/^other-models/(?P<pk>[^/.]+)/changelog/$
/plugins/example-app/^other-models/(?P<pk>[^/.]+)/notes/$
nautobot.apps.utils.get_view_for_model(model, view_type='')
¶
Return the UIViewSet
or <view_type>View
class associated with a given model
.
The view class is expected to be in the views
module within the app associated with the model,
and its name is expected to be either {ModelName}UIViewSet
or {ModelName}{view_type}View
.
If neither view class is found, this will return None
.
nautobot.apps.utils.get_worker_count(request=None, queue=None)
¶
Return a count of the active Celery workers in a specified queue. Defaults to the CELERY_TASK_DEFAULT_QUEUE
setting.
nautobot.apps.utils.hex_to_rgb(hex_str)
¶
Map a hex string like "00ff00" to individual r, g, b integer values.
nautobot.apps.utils.image_upload(instance, filename)
¶
Return a path for uploading image attachments.
nautobot.apps.utils.is_url(value)
¶
Validate whether a value is a URL.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
str
|
String to validate. |
required |
Returns:
Type | Description |
---|---|
bool
|
True if the value is a valid URL, False otherwise. |
nautobot.apps.utils.lighten_color(r, g, b, factor)
¶
Make a given RGB color lighter (closer to white).
nautobot.apps.utils.merge_dicts_without_collision(d1, d2)
¶
Merge two dicts into a new dict, but raise a ValueError if any key exists with differing values across both dicts.
nautobot.apps.utils.migrate_content_type_references_to_new_model(apps, old_ct, new_ct)
¶
When replacing a model, this will update references to the content type on related models such as tags and object changes.
Since this only updates the content type and not the primary key, this is typically only useful when migrating to a new model and preserving the old instance's primary key.
This will replace the old content type with the new content type on the following models
- ComputedField.content_type
- CustomLink.content_type
- ExportTemplate.content_type
- Note.assigned_object_type
- ObjectChange.changed_object_type
- Relationship.source_type
- Relationship.destination_type
- RelationshipAssociation.source_type
- RelationshipAssociation.destination_type
- TaggedItem.content_type
For these one-to-many and many-to-many relationships, the new content type is added to the related model's content type list, but the old content type is not removed: - CustomField.content_types - JobButton.content_types - JobHook.content_types - ObjectPermission.object_types - Status.content_types - Tag.content_types - WebHook.content_types
This will also fix tags that were not properly enforced by adding the new model's content type to the tag's content types if an instance of the new model is using the tag.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
apps |
obj
|
An instance of the Django 'apps' object. |
required |
old_ct |
obj
|
An instance of ContentType for the old model. |
required |
new_ct |
obj
|
An instance of ContentType for the new model. |
required |
nautobot.apps.utils.migrate_role_data(model_to_migrate, *, from_role_field_name, from_role_model=None, from_role_choiceset=None, to_role_field_name, to_role_model=None, to_role_choiceset=None, is_m2m_field=False)
¶
Update all model_to_migrate
with a value for to_role_field
based on from_role_field
values.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model_to_migrate |
Model
|
Model with role fields to alter |
required |
from_role_field_name |
str
|
Name of the field on |
required |
from_role_model |
Model
|
If |
None
|
from_role_choiceset |
ChoiceSet
|
If |
None
|
to_role_field_name |
str
|
Name of the field on |
required |
to_role_model |
Model
|
If |
None
|
to_role_choiceset |
ChoiceSet
|
If |
None
|
is_m2m_field |
bool
|
True if the role fields are both ManyToManyFields, else False |
False
|
nautobot.apps.utils.normalize_querydict(querydict, form_class=None)
¶
Convert a QueryDict to a normal, mutable dictionary, preserving list values. For example,
QueryDict('foo=1&bar=2&bar=3&baz=')
becomes:
{'foo': '1', 'bar': ['2', '3'], 'baz': ''}
This function is necessary because QueryDict does not provide any built-in mechanism which preserves multiple values.
A form_class
can be provided as a way to hint which query parameters should be treated as lists.
nautobot.apps.utils.permission_is_exempt(name)
¶
Determine whether a specified permission is exempt from evaluation.
:param name: Permission name in the format
nautobot.apps.utils.populate_model_features_registry(refresh=False)
¶
Populate the registry model features with new apps.
This function updates the registry model features.
Behavior:
- Defines a list of dictionaries called lookup_confs. Each dictionary contains:
- 'feature_name': The name of the feature to be updated in the registry.
- 'field_names': A list of names of fields that must be present in order for the model to be considered
a valid model_feature.
- 'field_attributes': Optional dictionary of attributes to filter the fields by. Only model which fields match
all the attributes specified in the dictionary will be considered. This parameter can be
useful to narrow down the search for fields that match certain criteria. For example, if
field_attributes
is set to {"related_model": RelationshipAssociation}, only fields with
a related model of RelationshipAssociation will be considered.
- Looks up all the models in the installed apps.
- For each dictionary in lookup_confs, calls lookup_by_field() function to look for all models that have fields with the names given in the dictionary.
- Groups the results by app and updates the registry model features for each app.
nautobot.apps.utils.refresh_job_model_from_job_class(job_model_class, job_class)
¶
Create or update a job_model record based on the metadata of the provided job_class.
Note that job_model_class is a parameter (rather than doing a "from nautobot.extras.models import Job") because this function may be called from various initialization processes (such as the "nautobot_database_ready" signal) and in that case we need to not import models ourselves.
nautobot.apps.utils.remove_prefix_from_cf_key(field_name)
¶
field_name (str): f"cf_{cf.key}"
Helper method to remove the "cf_" prefix
nautobot.apps.utils.render_jinja2(template_code, context)
¶
Render a Jinja2 template with the provided context. Return the rendered content.
nautobot.apps.utils.resolve_permission(name)
¶
Given a permission name, return the app_label, action, and model_name components. For example, "dcim.view_location" returns ("dcim", "view", "location").
:param name: Permission name in the format
nautobot.apps.utils.resolve_permission_ct(name)
¶
Given a permission name, return the relevant ContentType and action. For example, "dcim.view_location" returns (Location, "view").
:param name: Permission name in the format
nautobot.apps.utils.rgb_to_hex(r, g, b)
¶
Map r, g, b values to a hex string.
nautobot.apps.utils.sanitize(dirty, replacement='(redacted)')
¶
Make an attempt at stripping potentially-sensitive information from the given string, bytes or iterable thereof.
Obviously this will never be 100% foolproof but we can at least try.
Uses settings.SANITIZER_PATTERNS as the list of (regexp, repl) tuples to apply.
nautobot.apps.utils.shallow_compare_dict(source_dict, destination_dict, exclude=None)
¶
Return a new dictionary of the different keys. The values of destination_dict
are returned. Only the equality of
the first layer of keys/values is checked. exclude
is a list or tuple of keys to be ignored.
nautobot.apps.utils.swap_status_initials(data)
¶
Swap Git status initials with its equivalent.
nautobot.apps.utils.task_queues_as_choices(task_queues)
¶
Returns a list of 2-tuples for use in the form field choices
argument. Appends
worker count to the description.
nautobot.apps.utils.to_meters(length, unit)
¶
Convert the given length to meters.
nautobot.apps.utils.wrap_model_clean_methods()
¶
Helper function that wraps plugin model validator registered clean methods for all applicable models