如何解决Django 无法识别/找不到 post_save 编辑的字段?
我正在尝试使用 post_save 模型信号创建一个独特的 SlugField。如果 SlugField 已存在,则应在 slug 后附加一个数字以使其唯一。
然而,当 SlugField 已经存在时,Django 似乎无法识别。
我使用的是单表继承的 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 字段(lft
、rght
、level
、get_root()
等)我实际上有另一个名为 Chapter
的 STI 模型,它将利用 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,**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
实际上是另一个问题(我计算订单的方法是错误的),我将在另一个线程上发布...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。