Django 没有 recognize/can 找不到 post_save 编辑的字段?

Django doesn't recognize/can't find post_save edited field?

我正在尝试使用 post_save 模型信号创建一个独特的 SlugField。如果 SlugField 已经存在,则应将一个数字附加到 slug 以使其唯一。

但是,Django 似乎无法识别 SlugField 何时已经存在。

我正在使用单表继承 MPTT 模型:

class Text(MPTTModel):
    type = models.CharField(max_length=255, blank=False)  # for STI. Essentially returns the class name.
    title = models.CharField(max_length=255, blank=True)
    slug = models.SlugField(max_length=255, blank=True)
    slug_order = models.CharField(max_length=255, blank=True)

    def __init__(self, *args, **kwargs):
        super(Text, self).__init__(*args, **kwargs)
        # If we don't have a subclass at all, then we need the type attribute to match
        # our current class.
        if not self.__class__.__subclasses__():
            self.type = self.__class__.__name__.lower()
        else:
            subclass = [
                x
                for x in self.__class__.__subclasses__()
                if x.__name__.lower() == self.type
            ]
            if subclass:
                self.__class__ = subclass[0]
            else:
                self.type = self.__class__.__name__.lower()

class Book(Text):
    objects = BookManager()

    class Meta:
        proxy = True

@receiver(post_save, sender=Book, dispatch_uid="create_book_slug")
def create_book_slug(sender, instance, **kwargs):
    slug = slugify(instance.title)
    slug_exists = Book.objects.filter(slug=slug).exists() # This always seems to be False
    counter = 1
    while slug_exists:
        counter += 1
        new_slug = f"{slug}-{counter}"
        slug_exists = Book.objects.filter(slug=new_slug).exists()
    if counter > 1:
        slug = f"{slug}-{counter}"
    instance.slug = slug

我的测试:

b1 = Book.objects.create(title="book book")
b2 = Book.objects.create(title="book book")

self.assertEqual(b1.slug, "book-book") # True
self.assertEqual(b2.slug, "book-book-2") # False - b2.slug gives "book-book"
self.assertEqual(b1.slug, b2.slug) # This is True... obviously not what I want.

self.assertEqual(Book.objects.filter(slug=b1.slug).exists(), True) # False. I have no idea why.

self.assertEqual(Book.objects.filter(title=b1.title).exists(), True) # True. This works.

我必须使用 post_save,因为我实际上想利用默认的 MPTT 字段(lftrghtlevelget_root() 等。 ) 我实际上有另一个 STI 模型称为 Chapter,它将利用 slug_order:

class Chapter(Text):
    objects = ChapterManager()

    class Meta:
        proxy = True

@receiver(post_save, sender=Chapter, dispatch_uid="create_chapter_slug")
def create_chapter_slug(sender, instance, **kwargs):
    print(instance.get_root()) # This works and points to the Chapter's top parent
    print(instance.get_root().slug) # This doesn't work and returns nothing
    instance.slug = instance.get_root().slug

    # slug_order code below works
    order = instance.rght - instance.lft
    if instance.level == 1:
        instance.slug_order = order
    else:
        instance.slug_order = f"{instance.parent.slug_order}/{order}"

看起来 post_save 信号实际上并没有保存。

b1 = Book.objects.create(title="book book")
self.assertEqual(b1.slug, "book-book") # True

b1.refresh_from_db()
self.assertEqual(b1.slug, "") # True

并且将 instance.save() 添加到 post_save 接收器会产生递归错误。

我最初的问题是通过使用 pre_save 而不是 create_book_slug 来解决的。

我的 create_chapter_slug 实际上是另一个问题(我计算顺序的方法是错误的),我将在另一个线程上发布...