Почему не работает переопределение функции Model.save () в Django? - PullRequest
3 голосов
/ 27 марта 2011

Я новичок в SO и Python / Django, поэтому, пожалуйста, потерпите меня.

В моем общем блог-приложении, основанном на учебнике по http://www.djangoproject.com/, Я пытаюсь создавать слагов для сообщений, когдаони сохраняются в базе данных с помощью метода 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 ]

3 голосов
/ 28 марта 2011

modocache,

Какую версию django вы используете?То, что вы там перечислили, должно работать, я использую ту же логику во многих моих собственных моделях, и она отлично работает.

Согласно этой странице: http://fosshelp.blogspot.com/2010/12/django-override-save-method-two-ways.html

вы сможете изменить код так, чтобы он выглядел так (ниже), и он будет делать то же самое, но не будет ссылаться на сообщениемодель.

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

Еще один момент, вместо использования "если не self.id:", как правило, лучше использовать вместо него "если не self.pk:".см. эти связанные ссылки.

Запросы Django - id против pk

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

Как это помогает.

1 голос
/ 28 марта 2011

Мне интересно, есть ли у вас ошибка отступа в вашей строке super() - у вас есть символы табуляции и пробелы?

При запуске сервера даже ввод super(IDONTEXIST, self) не должен выдавать ошибку, пока не будет вызван save().

Я могу воспроизвести твою ошибку, если сделаю отступ в суперлине.

...