为什么Django中Model.save()函数的重写无效?

4 投票
2 回答
4077 浏览
提问于 2025-04-16 14:31

我刚开始接触Stack Overflow和Python/Django,所以请多多包涵。

在我根据http://www.djangoproject.com/的教程制作的通用博客应用中,我想在保存文章到数据库时,为文章的标题生成一个“slug”。我使用了slugify()这个方法。这里是posts.models.py的代码:

from django.db import models
from django.template.defaultfilters import slugify
import datetime

class Post( models.Model ):

    def __unicode__(self):
        return self.title

    title = models.CharField( max_length = 200 )
    slug  = models.SlugField( editable = False )
    body = models.TextField()
    pub_date = models.DateTimeField('date published')

    def save(self, *args, **kwargs):
        if not self.id:
            self.slug = slugify( self.title )
        super( Post, self ).save( *args, **kwargs )

不幸的是,当我尝试启动服务器时,出现了以下错误:

File "/Users/modocache/Programming/Django/blog/posts/models.py", line 24, in Post
super( Post, self ).save( *args, **kwargs )
NameError: name 'Post' is not defined

我对为什么会出现NameError感到困惑。我以为我使用super()方法的方式不对,但这个方法可以正常工作,尽管看起来和我上面尝试的差不多:

class Foo( object ):
    def say_spam( self ):
        print "Spam!"

class Bar( Foo ):
    def say_spam( self ):
        print "Brought to you by:"
        super( Bar, self ).say_spam()
        print "Eggs!"

b = Bar()
b.say_spam()

既然这个可以正常工作,为什么上面的Django代码片段就不行呢?这让我特别困惑,因为djangoproject.com的文档说这个应该可以正常运行:

# http://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def save(self, *args, **kwargs):
        do_something()
        super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
        do_something_else()

非常感谢大家的帮助,我会很感激的!

2 个回答

1

我在想,你的 super() 这一行是不是有缩进错误——你是不是把制表符和空格搞混了?

在启动服务器时,即使输入 super(IDONTEXIST, self) 也不应该报错,直到你调用 save()

如果我把 super 这一行的缩进去掉,我就能复现你的错误。

4

modocache,

你在用哪个版本的Django?你列出的内容应该是可以工作的,我在自己的很多模型中也用过同样的逻辑,效果很好。

根据这个页面:http://fosshelp.blogspot.com/2010/12/django-override-save-method-two-ways.html

你可以把代码改成下面这样,它会做同样的事情,但不会引用Post模型。

 def save(self, *args, **kwargs):
    if not self.id:
        self.slug = slugify( self.title )
    models.Model.save(self, *args, **kwargs ) # <-- notice the self

还有一点,通常来说,使用“if not self.id:”不如用“if not self.pk:”来得好。可以看看这些相关链接。

Django查询 - id和pk的区别

http://docs.djangoproject.com/en/dev/ref/models/instances/#the-pk-property

希望这些对你有帮助。

撰写回答