|
|
|
from django.db import models
|
|
|
|
from django.utils.crypto import get_random_string
|
|
|
|
|
|
|
|
try:
|
|
|
|
from django_scopes import scopes_disabled
|
|
|
|
except ImportError:
|
|
|
|
scopes_disabled = False
|
|
|
|
|
|
|
|
|
|
|
|
class RandomSlugMixin(models.Model):
|
|
|
|
"""
|
|
|
|
some alternatives for slug_chars:
|
|
|
|
abcdeghjkpqrsxyz23456789 # 24 chars, max clarity while being all lowercase
|
|
|
|
ABCDGHKLMNQRTabcdeghjr23456789 # 30 chars, max clarity mixed case
|
|
|
|
abcdefghijkmnpqrstuwxyz123467890 # 32 chars, all lowercase
|
|
|
|
"""
|
|
|
|
slug_chars = 'abcdefghijkmnpqrstuwxyz123467890'
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
abstract = True
|
|
|
|
|
|
|
|
slug = models.CharField(max_length=6, unique=True)
|
|
|
|
|
|
|
|
def save(self, **kwargs):
|
|
|
|
self.generate_slug()
|
|
|
|
super().save(**kwargs)
|
|
|
|
|
|
|
|
def generate_slug(self):
|
|
|
|
if not self.slug:
|
|
|
|
self.slug = self.generate_new_slug()
|
|
|
|
|
|
|
|
def generate_new_slug(self):
|
|
|
|
slug = get_random_string(self.slug_length, self.slug_chars)
|
|
|
|
if self.__class__.objects.filter(slug=slug).exists():
|
|
|
|
return self.generate_new_slug()
|
|
|
|
return slug
|
|
|
|
|
|
|
|
@property
|
|
|
|
def slugs_available(self):
|
|
|
|
return self.slug_count_total - self.__class__.objects.count()
|
|
|
|
|
|
|
|
@property
|
|
|
|
def slug_count_total(self):
|
|
|
|
return len(self.slug_chars) ** self.slug_length
|
|
|
|
|
|
|
|
@property
|
|
|
|
def slug_length(self):
|
|
|
|
return self.__class__._meta.get_field('slug').max_length
|
|
|
|
|
|
|
|
if scopes_disabled:
|
|
|
|
generate_new_slug = scopes_disabled(generate_new_slug)
|
|
|
|
slugs_available = scopes_disabled(slugs_available)
|
|
|
|
|
|
|
|
|
|
|
|
class RandomSlugPKMixin(RandomSlugMixin):
|
|
|
|
slug = models.CharField(max_length=6, unique=True, primary_key=True)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
abstract = True
|