3

I am getting an error in Django saying Caught TypeError while rendering: sequence item 1: expected string or Unicode, Property found. Here is my code:

def __unicode__( self ) :
    return "{} : {}".format( self.name, self.location )

I even tried

def __unicode__( self ) :
    return unicode( "{} : {}".format( self.name, self.location ) )

but the same error.

From what I know "this is x = {}".format( x ) returns a string right? Why is Python saying it's a Property?

Full code:

class Item( models.Model ) :
    def __unicode__( self ) :
        return "{} : {}".format( self.name, self.location )

    name       = models.CharField( max_length = 135 )
    comment    = models.TextField( blank = True )
    item_type  = models.ForeignKey( ItemType )
    location   = models.ForeignKey( Location )
    t_created  = models.DateTimeField( auto_now_add = True, verbose_name = 'created' )
    t_modified = models.DateTimeField( auto_now = True, verbose_name = 'modified' )

class Location( models.Model ) :
    def __unicode__( self ) :
        locations = filter( None, [ self.room, self.floor, self.building ] )
        locations.append( self.prop )

        return ", ".join( locations ) # This will look in the form of like "room, floor, building, property"

    comment    = models.TextField( blank = True )
    room       = models.CharField( max_length = 135, blank = True )
    floor      = models.CharField( max_length = 135, blank = True )
    building   = models.CharField( max_length = 135, blank = True )
    prop       = models.ForeignKey( Property )
    t_created  = models.DateTimeField( auto_now_add = True, verbose_name = 'created' )
    t_modified = models.DateTimeField( auto_now = True, verbose_name = 'modified' )

class Property( models.Model ) :
    def __unicode__( self ) :
        return self.name

    name = models.CharField( max_length = 135 )
2
  • 1
    Looks like it's saying self.name is something it can't turn into a string. Could you show how self.name is defined? Commented Mar 8, 2012 at 22:59
  • @hobbes3: That is obviously not the full code (most importantly, the module models is missing). Commented Mar 8, 2012 at 23:23

2 Answers 2

1

Property isn't referring to a Python property, but to your Property class. What's probably happening is this:

  1. Item.__unicode__ gets called.
  2. It grabs self.name and self.location.
  3. self.name returns a unicode string from its __unicode__ method.
  4. self.location is a foreign key, so Location.__unicode__ gets called.
  5. That gets self.room, self.floor, and self.building, which all have __unicode__ methods that return unicode strings.
  6. filter sees that these strings are all empty, so locations is set to [].
  7. self.prop, which is a Property, gets appended to locations.
  8. ", ".join( locations ) Throws a TypeError because a Property isn't a string.
  9. the str.format call in Item.__unicode__ catches that exception and throws its own, which is what you see.

Solution: change

locations.append( self.prop )

to

locations.append( unicode(self.prop) )

Moral: str.format calls str() on its arguments, but str.join does not.

Sign up to request clarification or add additional context in comments.

1 Comment

Great explanation! I am a little confused about one part though. If you say that self.prop calls Property.__unicode__, then isn't Property.__unicode__ also a return a unicode string since it just returns self.name? Why do I need to do unicode( self.prop )? I'm assuming I always have to do that with a ForeignKey, but a little clarification would be nice :-).
0

Have you tried?:

def __unicode__( self ):
    return "{name}: {location}".format(name=self.name, location=self.location)

or

def __unicode__( self ):
    return "{0}: {1}".format(self.name, self.location)

or

def __unicode__( self ):
    return "%s: %s" % (self.name, self.location)

Hope it helps :)

1 Comment

None of those have any real semantic difference from his code, so if the behavior changed, it would be due to a bug in python.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.