73 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""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,
 | 
						|
        )
 |