[英]Django doesn't recognize/can't find post_save edited field?
I'm trying to create a unique SlugField using a post_save model signal.我正在尝试使用 post_save model 信号创建一个独特的 SlugField。 If the SlugField already exists, a number should be appended to the slug to make it unique.
如果 SlugField 已经存在,则应将一个数字附加到 slug 以使其唯一。
However, Django does not seem to to recognize when the SlugField already exists.但是,Django 似乎无法识别 SlugField 何时已存在。
I'm using a single-tabled inherited MPTT model:我正在使用单表继承的 MPTT model:
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
My test:我的测试:
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.
I have to use post_save
as I actually want to leverage the default MPTT fields ( lft
, rght
, level
, get_root()
etc.) I actually have another STI model called Chapter
that has will utilize slug_order
:我必须使用
post_save
因为我实际上想利用默认的 MPTT 字段( lft
, rght
, level
, get_root()
等)我实际上有另一个 STI model 称为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}"
Looks like the the post_save
signal doesn't actually save.看起来
post_save
信号实际上并没有保存。
ie IE
b1 = Book.objects.create(title="book book")
self.assertEqual(b1.slug, "book-book") # True
b1.refresh_from_db()
self.assertEqual(b1.slug, "") # True
And adding instance.save()
to the post_save
receiver gives a recursion error.并且将
instance.save()
添加到post_save
接收器会产生递归错误。
My initial problem is solved with using pre_save
instead for the create_book_slug
.使用
pre_save
代替create_book_slug
解决了我最初的问题。
My create_chapter_slug
is actually a whole other problem (my method for calculating the order is wrong) that I will be posting on another thread...我的
create_chapter_slug
实际上是另一个问题(我计算顺序的方法是错误的),我将在另一个线程上发布......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.