content: from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
  from django.core.validators import MaxValueValidator, MinValueValidator
  from django.db import models
  from django.utils.translation import gettext_lazy as _
  
  from ipam.choices import *
  from ipam.constants import *
  from netbox.models import ChangeLoggedModel, PrimaryModel
  
  __all__ = (
      'FHRPGroup',
      'FHRPGroupAssignment',
  )
  
  
  class FHRPGroup(PrimaryModel):
      """
      A grouping of next hope resolution protocol (FHRP) peers. (For instance, VRRP or HSRP.)
      """
      group_id = models.PositiveSmallIntegerField(
          verbose_name=_('group ID')
      )
      name = models.CharField(
          verbose_name=_('name'),
          max_length=100,
          blank=True
      )
      protocol = models.CharField(
          verbose_name=_('protocol'),
          max_length=50,
          choices=FHRPGroupProtocolChoices
      )
      auth_type = models.CharField(
          max_length=50,
          choices=FHRPGroupAuthTypeChoices,
          blank=True,
          null=True,
          verbose_name=_('authentication type')
      )
      auth_key = models.CharField(
          max_length=255,
          blank=True,
          verbose_name=_('authentication key')
      )
      ip_addresses = GenericRelation(
          to='ipam.IPAddress',
          content_type_field='assigned_object_type',
          object_id_field='assigned_object_id',
          related_query_name='fhrpgroup'
      )
      services = GenericRelation(
          to='ipam.Service',
          content_type_field='parent_object_type',
          object_id_field='parent_object_id',
          related_query_name='fhrpgroup',
      )
  
      clone_fields = ('protocol', 'auth_type', 'auth_key', 'description')
  
      class Meta:
          ordering = ['protocol', 'group_id', 'pk']
          verbose_name = _('FHRP group')
          verbose_name_plural = _('FHRP groups')
  
      def __str__(self):
          name = ''
          if self.name:
              name = f'{self.name} '
  
          name += f'{self.get_protocol_display()}: {self.group_id}'
  
          # Append the first assigned IP addresses (if any) to serve as an additional identifier
          if self.pk:
              ip_address = self.ip_addresses.first()
              if ip_address:
                  return f"{name} ({ip_address})"
  
          return name
  
  
  class FHRPGroupAssignment(ChangeLoggedModel):
      interface_type = models.ForeignKey(
          to='contenttypes.ContentType',
          on_delete=models.CASCADE
      )
      interface_id = models.PositiveBigIntegerField()
      interface = GenericForeignKey(
          ct_field='interface_type',
          fk_field='interface_id'
      )
      group = models.ForeignKey(
          to='ipam.FHRPGroup',
          on_delete=models.CASCADE
      )
      priority = models.PositiveSmallIntegerField(
          verbose_name=_('priority'),
          validators=(
              MinValueValidator(FHRPGROUPASSIGNMENT_PRIORITY_MIN),
              MaxValueValidator(FHRPGROUPASSIGNMENT_PRIORITY_MAX)
          )
      )
  
      clone_fields = ('interface_type', 'interface_id')
  
      class Meta:
          ordering = ('-priority', 'pk')
          indexes = (
              models.Index(fields=('interface_type', 'interface_id')),
          )
          constraints = (
              models.UniqueConstraint(
                  fields=('interface_type', 'interface_id', 'group'),
                  name='%(app_label)s_%(class)s_unique_interface_group'
              ),
          )
          verbose_name = _('FHRP group assignment')
          verbose_name_plural = _('FHRP group assignments')
  
      def __str__(self):
          return f'{self.interface}: {self.group} ({self.priority})'
  
      def get_absolute_url(self):
          # Used primarily for redirection after creating a new assignment
          if self.interface:
              return self.interface.get_absolute_url()
          return None
  