Django Model.object.get 预保存函数异常
我写了一个函数,用来连接模型的 'pre_save' 信号。在这个函数里,我想检查一下模型实例的主键(pk)是否已经存在于表中,方法是:
sender.objects.get(pk=instance._get_pk_val())
第一次创建这个模型时出现了错误。我捕捉到这个错误,然后根据标题生成了一个 slug 字段。第二次创建实例时就没有抛出错误。我检查了两个实例的 instance._get_pk_val() 的值,它们都是一样的:None
所以:
# This one raises an error in the sluggit function
instance1 = Model(title="title 1")
instance1.save()
# This one doesn't raise an error
instance2 = Model(title="title 2")
instance2.save()
这是我玩 Python 和 Django 的第三天。如果我没看懂什么新手的东西,真抱歉。
编辑:
模型:
class Test(models.Model):
title = models.CharField(max_length=128)
slug = models.SlugField(max_length=128)
slug.prepopulate_from=('title',)
signals.pre_save.connect(package.sluggit, sender=Test)
函数的基本内容:
def sluggit(sender, instance, signal, *args, **kwargs):
try:
sender.objects.get(pk=instance._get_pk_val())
except:
# Generate Slug Code
@S.Lot 在评论中告诉我可以重写 save() 方法。我得试试这个。不过我还是想知道为什么第二次调用 model.objects.get() 时没有抛出错误。
编辑 2
谢谢 @S.Lot。重写 save 方法效果很好。我还是对信号方法感到好奇。嗯,有点奇怪。
编辑 3
经过更多的尝试,我发现使用 instance.objects.get() 而不是 sender.objects.get() 是有效的:
def sluggit(sender, instance, signal, *args, **kwargs):
try:
sender.objects.get(pk=instance._get_pk_val())
except:
# Generate Slug Code
应该是:
def sluggit(sender, instance, signal, *args, **kwargs):
try:
instance.objects.get(pk=instance._get_pk_val())
except:
# Generate Slug Code
这是个bug吗?我之前以为 sender.objects.get() 和 Test.objects.get() 是一样的。
2 个回答
谢谢你发这个帖子。现在谷歌搜索的结果(我发这个的时候)有点过时,显示的是连接信号的旧方法(听说最近这个方法已经改写了)。你修改后的内容和正确的代码示例让我明白了怎么做。
我希望更多的人能在他们的评论里加上修正的内容。谢谢你。:-)
S.Lott说得对……用save()
,因为你已经承认你开始这么做了。
至于信号的问题,我实话实说,我看不出你的代码有什么问题。我自己也在本地运行过,结果是成功的。你确定在提问时描述得准确吗?或者说instance2是不是已经是一个存在的数据库对象(也许是你测试代码中的一个小错误)?