Заполнение поля django с помощью pre_save ()? - PullRequest
45 голосов
/ 24 июня 2011
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, если нет, исправьте меня!

Во всяком случае, я искал pre_save () как еще один способ сделать это, но не могу понять, как это работает. Как вы делаете это с pre_save ()?

это как

def pre_save(self):
     self.slug = title

Наверное, нет. Какой код для этого?

Спасибо!

Ответы [ 5 ]

72 голосов
/ 24 июня 2011

Скорее всего, вы имеете в виду сигнал Джанго 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)

Если вы не включите аргумент отправителя в декоратор, например @receiver(pre_save, sender=MyModel), обратный вызов будет вызван для всех моделей.

Вы можете поместить код в любой файл, который анализируется во время выполнения вашего приложения, models.py является хорошим местом для этого.

21 голосов
/ 16 октября 2013
@receiver(pre_save, sender=TodoList)
def my_callback(sender, instance, *args, **kwargs):
    instance.slug = slugify(instance.title)
11 голосов
/ 22 декабря 2014

вы можете использовать сигналы 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") 
0 голосов
/ 20 мая 2019

Сигнальный крючок pre_save() действительно является отличным местом для проведения усадки для большого количества моделей.Хитрость заключается в том, чтобы узнать, какие модели требуют создания слагов, какое поле должно быть основой для значения слагов.

Для этого я использую декоратор классов, позволяющий помечать модели для генерации слагов, ина каком поле его основывать:

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

Обратите внимание, что нетсделана попытка сгенерировать уникальное значение slug.Это потребует проверки исключений целостности в транзакции или использования рандомизированного значения в слаге из достаточно большого пула, чтобы сделать коллизии маловероятными.Проверка исключения целостности может быть выполнена только в методе save(), а не в перехватчиках сигналов.

0 голосов
/ 25 декабря 2018

Функции приемника должны быть такими:

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

Обратите внимание, что функция принимает аргумент sender вместе с аргументами с подстановочными словами (** kwargs) ; все обработчики сигналов должны принимать эти аргументы.

Все сигналы отправляют аргументы ключевого слова и могут изменить эти аргументы ключевого слова в любое время.

Ссылка здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...