繁体   English   中英

使用 pre_save() 填充 Django 字段?

[英]Populating django field with pre_save()?

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

我猜没有。 执行此操作的代码是什么?

谢谢!

您很可能指的是django 的pre_save信号 你可以这样设置:

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是一个很好的地方。

@receiver(pre_save, sender=TodoList)
def my_callback(sender, instance, *args, **kwargs):
    instance.slug = slugify(instance.title)

您可以使用 django 信号。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") 

pre_save()信号钩子确实是处理大量模型slugification 的好地方。 诀窍是知道哪些模型需要生成 slug,哪些字段应该是 slug 值的基础。

我为此使用了一个类装饰器,它可以让我标记用于自动生成的模型,以及它基于什么字段:

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

这只会为特定模型注册一个信号处理程序,并允许您使用每个模型来改变源字段:

@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()

请注意,不会尝试生成唯一的slug 值。 这将需要检查事务中的完整性异常,或者在足够大的池中使用 slug 中的随机值,以使冲突不太可能发生。 完整性异常检查只能在save()方法中完成,不能在信号钩子中完成。

接收器函数必须是这样的:

def my_callback(sender, **kwargs):
    print("Request finished!")

请注意,该函数采用sender参数以及通配符关键字参数(**kwargs) 所有信号处理程序都必须采用这些参数。

所有信号都发送关键字参数,并且可以随时更改这些关键字参数。

参考这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM