1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00
Files
netbox-community-netbox/netbox/utilities/utils.py

114 lines
2.9 KiB
Python
Raw Normal View History

from django.db.models import Count, ManyToOneRel, OuterRef, Subquery
2020-12-17 14:45:50 -05:00
from django.db.models.functions import Coalesce
from django.utils import timezone
from django.utils.timezone import localtime
from .string import title
def dynamic_import(name):
"""
Dynamically import a class from an absolute path string
"""
components = name.split('.')
mod = __import__(components[0])
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
def count_related(model, field):
"""
Return a Subquery suitable for annotating a child object count.
"""
subquery = Subquery(
model.objects.filter(
**{field: OuterRef('pk')}
).order_by().values(
field
).annotate(
c=Count('*')
).values('c')
)
2020-12-17 14:45:50 -05:00
return Coalesce(subquery, 0)
def dict_to_filter_params(d, prefix=''):
"""
Translate a dictionary of attributes to a nested set of parameters suitable for QuerySet filtering. For example:
{
"name": "Foo",
"rack": {
"facility_id": "R101"
}
}
Becomes:
{
"name": "Foo",
"rack__facility_id": "R101"
}
And can be employed as filter parameters:
Device.objects.filter(**dict_to_filter(attrs_dict))
"""
params = {}
for key, val in d.items():
k = prefix + key
if isinstance(val, dict):
params.update(dict_to_filter_params(val, k + '__'))
else:
params[k] = val
return params
def content_type_name(ct, include_app=True):
"""
Return a human-friendly ContentType name (e.g. "DCIM > Site").
"""
2021-09-01 12:55:25 -04:00
try:
meta = ct.model_class()._meta
app_label = title(meta.app_config.verbose_name)
model_name = title(meta.verbose_name)
if include_app:
return f'{app_label} > {model_name}'
return model_name
2021-09-01 12:55:25 -04:00
except AttributeError:
# Model no longer exists
return f'{ct.app_label} > {ct.model}'
def content_type_identifier(ct):
"""
Return a "raw" ContentType identifier string suitable for bulk import/export (e.g. "dcim.site").
"""
return f'{ct.app_label}.{ct.model}'
def local_now():
"""
Return the current date & time in the system timezone.
"""
return localtime(timezone.now())
def get_related_models(model, ordered=True):
"""
Return a list of all models which have a ForeignKey to the given model and the name of the field. For example,
`get_related_models(Tenant)` will return all models which have a ForeignKey relationship to Tenant.
"""
related_models = [
(field.related_model, field.remote_field.name)
for field in model._meta.related_objects
if type(field) is ManyToOneRel
]
if ordered:
return sorted(related_models, key=lambda x: x[0]._meta.verbose_name.lower())
return related_models