class TodoList(models.Model):
title = models.CharField(maxlength=100)
slug = models.SlugField(maxlength=100)
def save(self):
self.slug = title
super(TodoList, self).save()
我假设上面是如何在将标题插入表TodoList时如何创建和存储slug,如果没有,请纠正我!
无论如何,我一直在研究pre_save()作为另一种方法,但无法弄清楚它是如何工作的。你是怎么用pre_save()做的?
就像
def pre_save(self):
self.slug = title
我猜不是。这样做的代码是什么?
谢谢!
答案 0 :(得分:70)
您最有可能指的是django's pre_save
signal。你可以设置这样的东西:
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)
如果你没有在装饰器中包含sender参数,比如@receiver(pre_save, sender=MyModel)
,那么将为所有模型调用回调。
您可以将代码放在执行应用期间解析的任何文件中,models.py
是一个很好的地方。
答案 1 :(得分:21)
@receiver(pre_save, sender=TodoList)
def my_callback(sender, instance, *args, **kwargs):
instance.slug = slugify(instance.title)
答案 2 :(得分:11)
你可以使用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")
答案 3 :(得分:0)
接收器功能必须是这样的:
def my_callback(sender, **kwargs):
print("Request finished!")
请注意,该函数带有 sender 参数,以及通配符关键字参数(** kwargs);所有信号处理程序都必须采用这些参数。
所有信号都会发送关键字参数,并可能随时更改这些关键字参数。
参考here。
答案 4 :(得分:0)
pre_save()
signal hook确实是处理大量模型的弹丸的好地方。诀窍是要知道需要生成什么模型的段塞,应该将哪个字段作为段塞值的基础。
为此,我使用了一个类装饰器,它可以让我标记用于自动生成子弹的模型,以及基于它的字段:
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)
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
这仅为特定型号注册信号处理程序,并允许您在装饰了每种型号的情况下更改源字段:
@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()
请注意,没有尝试生成 unique slug值。这将需要检查事务中的完整性异常,或者使用足够大的池中的数据块中的随机值来避免冲突。完整性异常检查只能在save()
方法中完成,而不能在信号挂钩中完成。