tags:

views:

113

answers:

3

I'm trying to set title_for_url but it shows up in my database as "<property object at 0x027427E0>". What am I doing wrong?

from django.db import models

class Entry(models.Model):

    def _get_title_for_url(self):
        title = "%s" % self.get_title_in_url_format()
        return title

    AUTHOR_CHOICES = (('001', 'John Doe'),)
    post_date = models.DateField()
    author = models.CharField(max_length=3, choices=AUTHOR_CHOICES)
    title = models.CharField(max_length=100, unique=True)
    body = models.TextField()
    image = models.ImageField(upload_to='image/blog')
    image.blank = 'true'
    title_for_url = models.CharField(max_length=100, editable=False, default=property(_get_title_for_url))

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        return "/blog/%s/" % self.get_title_in_url_format()        

    def get_title_in_url_format(self):
        "Returns the title as it will be displayed as a URL, stripped of special characters with spaces replaced by '-'."
        import re
        pattern = re.compile( '(\'|\(|\)|,)' )
        titleForUrl = pattern.sub('', self.title)
        pattern = re.compile( '( )' )
        titleForUrl = pattern.sub('-', titleForUrl)
        return titleForUrl.lower()
A: 

You can't use property() in a default:

.., default=property(_get_title_for_url))

The default value should be a constant. If you need to compute a missing value, use a pre_save hook.

Ned Batchelder
In fact, `default` can be a callable. But it must be the callable itself, not the result of a callable - eg `default=datetime.datetime.now` so you can't pass it any parameters and it can't be an instance method.
Daniel Roseman
Cool! I learned something...
Ned Batchelder
+1  A: 
title_for_url = models.CharField(max_length=100, editable=False, default=property(_get_title_for_url)

You couldn't do that way.. 'default' should be a value or a calable(with no args)... (property is not calable)

In your case you need to update a save method:

class Entry(models.Model):
    def save(self, *args, **kwargs):
       self.title_for_url = self.get_title_in_url_format()
       super(...).save(*args, **kwargs)
Pydev UA
@Pydev UA: I tried the above code, but it gives me a "global name 'self' is not defined" error. Also, what are the parameters for super() supposed to be? Thanks.
nbsp
A: 

This is the final version of what worked for me:

def save(self, *args, **kwargs):
    self.title = self.title.strip()
    self.title_for_url = self.get_title_in_url_format()
    super(Entry, self).save(*args, **kwargs)
nbsp