Skip to content

Instantly share code, notes, and snippets.

@Guilouf
Created June 5, 2024 12:40
Show Gist options
  • Save Guilouf/6ea3adbf3dec40cd4f16b37353bb1bc0 to your computer and use it in GitHub Desktop.
Save Guilouf/6ea3adbf3dec40cd4f16b37353bb1bc0 to your computer and use it in GitHub Desktop.
Django database generated slug
"""Register a custom SLQ function to convert a string to a slug
https://gist.github.com/abn/779166b0c766ce67351c588489831852
This example is using Postgresql
"""
from django.db import migrations
SLUGIFY_FUNCTION = """
CREATE OR REPLACE FUNCTION public.slugify(
v TEXT
) RETURNS TEXT
LANGUAGE plpgsql
STRICT IMMUTABLE AS
$function$
BEGIN
-- 1. trim trailing and leading whitespaces from text
-- 2. remove accents (diacritic signs) from a given text
-- 3. lowercase unaccented text
-- 4. replace non-alphanumeric (excluding hyphen, underscore) with a hyphen
-- 5. trim leading and trailing hyphens
RETURN trim(BOTH '-' FROM regexp_replace(lower(unaccent(trim(v))), '[^a-z0-9\\-_]+', '-', 'gi'));
END;
$function$;
"""
class Migration(migrations.Migration):
dependencies = [
('balles_track', '0007_township_centroid'),
]
operations = [
migrations.RunSQL(SLUGIFY_FUNCTION)
]
class SlugifyFunc(Func):
"""Call for the custom function defined in the migration"""
function = "SLUGIFY"
# Concat is not currently supported as Django 5.0 but should be in 5.1
# https://forum.djangoproject.com/t/using-generatedfield-with-postgres/27224
slugify_exp = ExpressionWrapper(
SlugifyFunc(
Concat(
"departement",
Value("-"),
"commune",
Value("-"),
"date",
),
),
output_field=models.SlugField()
)
# This does only works if the combination of brand, year and model is always unique
class Car(models.Model):
brand = ...
year = ...
model = ...
slug = models.GeneratedField(unique=True, expression=slugify_exp, db_persist=True, output_field=models.SlugField())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment