简体   繁体   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()

I'm assuming the above is how to create and store a slug when a title is inserted into the table TodoList, if not, please correct me!我假设上面是在表 TodoList 中插入标题时如何创建和存储 slug,如果不是,请纠正我!

Anyhow, I've been looking into pre_save() as another way to do this, but can't figure out how it works.无论如何,我一直在研究 pre_save() 作为另一种方法来做到这一点,但无法弄清楚它是如何工作的。 How do you do it with pre_save()?你如何用 pre_save() 做到这一点?

is it like是不是像

def pre_save(self):
     self.slug = title

I'm guessing no.我猜没有。 What is the code to do this?执行此操作的代码是什么?

Thanks!谢谢!

Most likely you are referring to django's pre_save signal .您很可能指的是django 的pre_save信号 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.如果您没有在装饰器中包含 sender 参数,例如@receiver(pre_save, sender=MyModel) ,则将为所有模型调用回调。

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.您可以将代码放在在应用程序执行期间解析的任何文件中, models.py是一个很好的地方。

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

you can use django signals.pre_save:您可以使用 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") 

The pre_save() signal hook is indeed a great place to handle slugification for a large number of models. pre_save()信号钩子确实是处理大量模型slugification 的好地方。 The trick is to know what models need slugs generated, what field should be the basis for the slug value.诀窍是知道哪些模型需要生成 slug,哪些字段应该是 slug 值的基础。

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.请注意,不会尝试生成唯一的slug 值。 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.这将需要检查事务中的完整性异常,或者在足够大的池中使用 slug 中的随机值,以使冲突不太可能发生。 Integrity exception checking can only be done in the save() method, not in signal hooks.完整性异常检查只能在save()方法中完成,不能在信号钩子中完成。

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) ;请注意,该函数采用sender参数以及通配符关键字参数(**kwargs) all signal handlers must take these arguments.所有信号处理程序都必须采用这些参数。

All signals send keyword arguments , and may change those keyword arguments at any time.所有信号都发送关键字参数,并且可以随时更改这些关键字参数。

Reference here .参考这里

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

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