114π
Most likely you are referring to djangoβs pre_save
signal. You could setup something like this:
from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.template.defaultfilters import slugify
@receiver(pre_save)
def my_callback(sender, instance, *args, **kwargs):
instance.slug = slugify(instance.title)
If you dont include the sender argument in the decorator, like @receiver(pre_save, sender=MyModel)
, the callback will be called for all models.
You can put the code in any file that is parsed during the execution of your app, models.py
is a good place for that.
31π
@receiver(pre_save, sender=TodoList)
def my_callback(sender, instance, *args, **kwargs):
instance.slug = slugify(instance.title)
- [Django]-Django Rest Framework β Updating a foreign key
- [Django]-Django class-based view: How do I pass additional parameters to the as_view method?
- [Django]-"<Message: title>" needs to have a value for field "id" before this many-to-many relationship can be used.
19π
you can use django signals.pre_save:
from django.db.models.signals import post_save, post_delete, pre_save
class TodoList(models.Model):
@staticmethod
def pre_save(sender, instance, **kwargs):
#do anything you want
pre_save.connect(TodoList.pre_save, TodoList, dispatch_uid="sightera.yourpackage.models.TodoList")
- [Django]-What's the best Django search app?
- [Django]-Adding a user to a group in django
- [Django]-How to get POST request values in Django?
16π
The pre_save()
signal hook is indeed a great place to handle slugification for a large number of models. The trick is to know what models need slugs generated, what field should be the basis for the slug value.
I use a class decorator for this, one that lets me mark models for auto-slug-generation, and what field to base it on:
from django.db import models
from django.dispatch import receiver
from django.utils.text import slugify
def autoslug(fieldname):
def decorator(model):
# some sanity checks first
assert hasattr(model, fieldname), f"Model has no field {fieldname!r}"
assert hasattr(model, "slug"), "Model is missing a slug field"
@receiver(models.signals.pre_save, sender=model, weak=False)
def generate_slug(sender, instance, *args, raw=False, **kwargs):
if not raw and not instance.slug:
source = getattr(instance, fieldname)
slug = slugify(source)
if slug: # not all strings result in a slug value
instance.slug = slug
return model
return decorator
This registers a signal handler for specific models only, and lets you vary the source field with each model decorated:
@autoslug("name")
class NamedModel(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField()
@autoslug("title")
class TitledModel(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField()
Note that no attempt is made to generate a unique slug value. That would require checking for integrity exceptions in a transaction or using a randomised value in the slug from a large enough pool as to make collisions unlikely. Integrity exception checking can only be done in the save()
method, not in signal hooks.
- [Django]-Is there a simple way to get group names of a user in django
- [Django]-Django urls without a trailing slash do not redirect
- [Django]-Django: Grab a set of objects from ID list (and sort by timestamp)
-4π
Receiver functions must be like this:
def my_callback(sender, **kwargs):
print("Request finished!")
Notice that the function takes a sender argument, along with wildcard keyword arguments (**kwargs); all signal handlers must take these arguments.
All signals send keyword arguments, and may change those keyword arguments at any time.
Reference here.
- [Django]-What's the cleanest, simplest-to-get running datepicker in Django?
- [Django]-How to override css in Django Admin?
- [Django]-Django dynamic model fields