3

I am new to SO and Python/Django, so please bear with me.

In my generic blog app based on the tutorial at http://www.djangoproject.com/, I am trying to create slugs for posts when they are saved to the database by using the slugify() method on the post's title. Here is 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 )

Unfortunately, this throws the following exception upon attempting to start the server:

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

I am confused as to why NameError is thrown. I thought I was using the super() method wrong, but this works, despite it seeming like the same thing I'm attempting above:

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()

So if this works, why doesn't the above Django snippet fail? This is especially puzzling considering djangoproject.com's documentation says this should work:

# 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()

Thanks for any and all help in advance, I'd really appreciate it!

Brian Gesiak
  • 6,648
  • 4
  • 35
  • 50

2 Answers2

4

modocache,

What version of django are you using? What you have there listed should work, I use that same logic in many of my own models, and it works fine.

According to this page: http://fosshelp.blogspot.com/2010/12/django-override-save-method-two-ways.html

you should be able to change the code to look like this (below), and it will do the same thing but won't reference the Post model.

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

Another point , instead of using "if not self.id:" it is generally better practice to use "if not self.pk:" instead. see these related links.

Django queries - id vs pk

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

How that helps.

Community
  • 1
  • 1
Ken Cochrane
  • 75,357
  • 9
  • 52
  • 60
  • Thanks, I now have the prettiest URLs on my block! As per your suggestion I changed super() to models.Model.save(), and now everything works fine. The apparent discrepancy between my models and yours in disconcerting, though. I'm using Django 1.3: In [5]: import django In [6]: django.get_version() Out[6]: '1.3' Thanks for all the cool links and the tip on pk! It was a big help. – Brian Gesiak Mar 27 '11 at 21:16
1

I'm wondering if you have an indentation error at your super() line -- do you have tabs and spaces mixed up?

Upon starting the server even typing in super(IDONTEXIST, self) should not throw an error until save() is called.

I can reproduce your error if I de-indent the super line.

Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245
  • Thanks for your help! Unindenting the line allowed me to start the server, but there's a functionality problem--the model only saves if the post is a new record! Which makes sense, considering existing records have self.id (or self.pk)'s, and therefore bypass the save() method. – Brian Gesiak Mar 27 '11 at 21:12
  • No problem, that's the mystery error for you there. The "functionality problem" is a common practice, to set a slug only on a new post or explicit change. – Yuji 'Tomita' Tomita Mar 27 '11 at 22:23