"""Generic models""" import re from django.core.validators import URLValidator from django.db import models from django.utils.regex_helper import _lazy_re_compile from model_utils.managers import InheritanceManager from rest_framework.serializers import BaseSerializer class SerializerModel(models.Model): """Base Abstract Model which has a serializer""" @property def serializer(self) -> BaseSerializer: """Get serializer for this model""" raise NotImplementedError class Meta: abstract = True class CreatedUpdatedModel(models.Model): """Base Abstract Model to save created and update""" created = models.DateTimeField(auto_now_add=True) last_updated = models.DateTimeField(auto_now=True) class Meta: abstract = True class InheritanceAutoManager(InheritanceManager): """Object manager which automatically selects the subclass""" def get_queryset(self): return super().get_queryset().select_subclasses() class InheritanceForwardManyToOneDescriptor( models.fields.related.ForwardManyToOneDescriptor ): """Forward ManyToOne Descriptor that selects subclass. Requires InheritanceAutoManager.""" def get_queryset(self, **hints): return self.field.remote_field.model.objects.db_manager( hints=hints ).select_subclasses() class InheritanceForeignKey(models.ForeignKey): """Custom ForeignKey that uses InheritanceForwardManyToOneDescriptor""" forward_related_accessor_class = InheritanceForwardManyToOneDescriptor class DomainlessURLValidator(URLValidator): """Subclass of URLValidator which doesn't check the domain (to allow hostnames without domain)""" def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.host_re = "(" + self.hostname_re + self.domain_re + "|localhost)" self.regex = _lazy_re_compile( r"^(?:[a-z0-9.+-]*)://" # scheme is validated separately r"(?:[^\s:@/]+(?::[^\s:@/]*)?@)?" # user:pass authentication r"(?:" + self.ipv4_re + "|" + self.ipv6_re + "|" + self.host_re + ")" r"(?::\d{2,5})?" # port r"(?:[/?#][^\s]*)?" # resource path r"\Z", re.IGNORECASE, )