Skip to content

Instantly share code, notes, and snippets.

@cessor
Created April 7, 2021 14:15
Show Gist options
  • Save cessor/8719060335163af468bcfba5b6546143 to your computer and use it in GitHub Desktop.
Save cessor/8719060335163af468bcfba5b6546143 to your computer and use it in GitHub Desktop.
AutoSlugField.py
from typing import Callable
from django.core import checks
from django.db import models
from django.utils.functional import cached_property
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
class AutoSlugField(models.SlugField):
"""
Generates a slug by slugifying the value of a
sibling field on the same model class.
"""
description = _("Auto Slug Field")
def __init__(self, *args, field: str,
slugify: Callable = slugify, **kwargs):
self.field = field
self.slugify = slugify
super().__init__(*args, **kwargs)
def check(self, **kwargs):
return [
*super().check(**kwargs),
*self._check_slugify_is_callable(**kwargs),
]
def _check_slugify_is_callable(self, **kwargs):
if not callable(self.slugify):
return [
checks.Error(
"'slugify' must be callable.",
obj=self,
id='fields.E001',
)
]
return []
def pre_save(self, model_instance, add):
if not getattr(model_instance, self.attname):
value = getattr(model_instance, self.field)
slug = self.slugify(value)
setattr(model_instance, self.attname, slug)
return slug
return super().pre_save(model_instance, add)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
if self.field is not None:
kwargs['field'] = self.field
if self.slugify is not None:
kwargs['slugify'] = self.slugify
return name, path, args, kwargs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment