Source code for tom_targets.models
from datetime import datetime
from dateutil.parser import parse
import logging
from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.module_loading import import_string
from tom_targets.base_models import BaseTarget
logger = logging.getLogger(__name__)
[docs]
def get_target_model_class():
"""Function to retrieve the target model class from settings.py. If not found, returns the default BaseTarget."""
base_class = BaseTarget
try:
TARGET_MODEL_CLASS = settings.TARGET_MODEL_CLASS
clazz = import_string(TARGET_MODEL_CLASS)
return clazz
except AttributeError:
return base_class
except ImportError as e:
raise ImportError(f'Could not import {TARGET_MODEL_CLASS}: {e}')
Target = get_target_model_class()
[docs]
class TargetName(models.Model):
"""
Class representing an alternative name for a ``Target``.
:param target: The ``Target`` object this ``TargetName`` is associated with.
:param name: The name that this ``TargetName`` object represents.
:type name: str
:param created: The time at which this target name was created in the TOM database.
:type created: datetime
:param modified: The time at which this target name was modified in the TOM database.
:type modified: datetime
"""
target = models.ForeignKey(BaseTarget, on_delete=models.CASCADE, related_name='aliases')
name = models.CharField(max_length=100, unique=True, verbose_name='Alias')
created = models.DateTimeField(
auto_now_add=True, help_text='The time at which this target name was created.'
)
modified = models.DateTimeField(
auto_now=True, verbose_name='Last Modified',
help_text='The time at which this target name was changed in the TOM database.'
)
[docs]
def __str__(self):
return self.name
[docs]
def validate_unique(self, *args, **kwargs):
"""
Ensures that Target.name and all aliases of the target are unique.
Called automatically when checking form.is_valid().
Should call TargetName.full_clean() to validate before save.
"""
super().validate_unique(*args, **kwargs)
# If nothing has changed for the alias, skip rest of uniqueness validation.
# We do not want to fail validation for existing objects, only newly added/updated ones.
if self.pk and self.name == TargetName.objects.get(pk=self.pk).name:
# Skip remaining uniqueness validation.
return
# If Alias name matches Target name, Return error
if self.name == self.target.name:
raise ValidationError(f'Alias {self.name} has a conflict with the primary name of the target. '
f'(target_id={self.target.id})')
# Check DB for similar target/alias names.
matches = Target.matches.match_name(self.name)
if matches:
raise ValidationError(f'Target with Name or alias similar to {self.name} already exists.'
f' ({matches.first().name})')
[docs]
class TargetList(models.Model):
"""
Class representing a list of targets in a TOM.
:param name: The name of the target list
:type name: str
:param targets: Set of ``Target`` objects associated with this ``TargetList``
:param created: The time at which this target list was created.
:type created: datetime
:param modified: The time at which this target list was modified in the TOM database.
:type modified: datetime
"""
name = models.CharField(max_length=200, help_text='The name of the target list.')
targets = models.ManyToManyField(BaseTarget)
created = models.DateTimeField(
auto_now_add=True, help_text='The time which this target list was created in the TOM database.'
)
modified = models.DateTimeField(
auto_now=True, verbose_name='Last Modified',
help_text='The time which this target list was changed in the TOM database.'
)
class Meta:
ordering = ('-created', 'name',)
[docs]
def __str__(self):
return self.name
def get_absolute_url(self):
return f'/targets/?targetlist__name={self.id}'
@property
def total_targets(self):
return self.targets.count()
[docs]
class PersistentShare(models.Model):
"""
Class representing a persistent share setup between a sharing destination and a Target
:param target: The ``Target`` you want to share
:param user: The ``User`` that created this PersistentShare, for accountability purposes.
:param destination: The sharing destination, as it appears in your TOM's DATA_SHARING settings dict
:type destination: str
:param created: The time at which this PersistentShare was created
:type created: datetime
"""
target = models.ForeignKey(BaseTarget, on_delete=models.CASCADE)
user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
destination = models.CharField(
max_length=200, help_text='The sharing destination, as it appears in your DATA_SHARING settings dict')
created = models.DateTimeField(
auto_now_add=True, help_text='The time which this PersistentShare was created in the TOM database.'
)
class Meta:
ordering = ('-created',)
unique_together = ['target', 'destination']
[docs]
def __str__(self):
return f'{self.target}-{self.destination}'