Подтвердить что ты не робот

Заполнение поля django с помощью 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, если нет, пожалуйста, исправьте меня!

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

это как

def pre_save(self):
     self.slug = title

Я предполагаю, что нет. Что такое код для этого?

Спасибо!

4b9b3361

Ответ 1

Скорее всего, вы обращаетесь к сигналу 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)

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

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

Ответ 2

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

Ответ 3

вы можете использовать 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") 

Ответ 4

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

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

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

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

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

Ответ 5

Сигнальный хук 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()

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