Skip to content

Instantly share code, notes, and snippets.

@denisorehovsky
Created April 1, 2018 09:17
Show Gist options
  • Save denisorehovsky/d3e8adc8c54cc4302dc506d995104e3e to your computer and use it in GitHub Desktop.
Save denisorehovsky/d3e8adc8c54cc4302dc506d995104e3e to your computer and use it in GitHub Desktop.
AutoSlugField
from django.db import models
from slugify import slugify
class AutoSlugField(models.CharField):
def __init__(self, populate_from, *args, always_update=False,
to_lower=False, max_length=50, **kwargs):
self.populate_from = populate_from
self.always_update = always_update
self.to_lower = to_lower
super().__init__(*args, max_length=max_length, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
kwargs['populate_from'] = self.populate_from
if self.always_update:
kwargs['always_update'] = self.always_update
if self.to_lower:
kwargs['to_lower'] = self.to_lower
if self.max_length != 50:
kwargs['max_length'] = self.max_length
return name, path, args, kwargs
def get_internal_type(self):
return 'AutoSlugField'
def pre_save(self, instance, add):
value = self.value_from_object(instance)
if self.always_update or not value:
value = self.get_prepopulated_value(instance)
slug = self.slugify(value)
if self.unique:
slug = self.generate_unique_slug(instance, slug)
setattr(instance, self.name, slug)
return slug
def slugify(self, value):
return slugify(value, to_lower=self.to_lower)
def generate_unique_slug(self, instance, slug):
new_slug = slug
suffix = 2
while (instance
.__class__
._default_manager
.filter(slug=new_slug)
.exists()):
new_slug = '{slug}-{suffix}'.format(slug=slug, suffix=suffix)
suffix += 1
return new_slug
def get_prepopulated_value(self, instance):
"""
Returns preliminary value based on `populate_from`.
"""
if callable(self.populate_from):
return self.populate_from(instance)
else:
attr = getattr(instance, self.populate_from)
return callable(attr) and attr() or attr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment