views:

85

answers:

3

I want to be able to show if an Image has been associated with each Product from the list_display view. I seem to be having trouble because I'm dealing with an associated object.

models.py

class ImageMain(models.Model):
    """This is the Main Image of the product"""
    product = models.ForeignKey(Product)
    photo = models.ImageField(upload_to='lcdtvs')  
    pub_date = models.DateTimeField('date published', auto_now_add=True)

class Product(models.Model):
   name = models.CharField(max_length=100)
   poll = models.ForeignKey(Poll)
   pub_date = models.DateTimeField('date published', auto_now_add=True)
   size = models.IntegerField(default=0)

admin.py

def photo_for_product(obj):
    images = obj.imagemain_set.all()
    return images[0].photo

class ProductAdmin(admin.ModelAdmin):
   list_display = ('name', "photo_for_product")
   inlines = [DescriptionInline, FeatureInline, AffiliateInline]

   def upper_case_name(self, obj):
       return ("%s" % (obj.name)).upper()

   def photo_for_product(self, obj):
       images = self.imagemain_set.all()
       return images[0].photo

admin.site.register(ImageMain)
admin.site.register(Product, ProductAdmin)

For some reason, the upper_case_name() displays fine in the list view. The photo_for_product() just keeps displaying (None).

I also tried use pdb in the photo_for_product method, but Django doesn't like that.

I also tried to put the callable before the ModelAdmin method, however, that created a lot of errors:

ProductAdmin.list_display[1], 'photo_for_product' is not a callable or an attribute of 'ProductAdmin' or found in the model 'Product'.
+1  A: 

Write a method that returns the necessary information as a string and add the name of the method to list_displays on your admin class.

Jeff Ober
+2  A: 

It's not clear from your question exactly what you want the output to be. You say you want to know "if an image has been associated" - if so, you could try this:

def photo_for_product(self, obj):
    images = self.imagemain_set.all()
    if images:
        return True
    else:
        return False
photo_for_product.boolean = True

If you want to actually see the image, you'll need to return some HTML that renders it in an img tag.

def photo_for_product(self, obj):
    images = self.imagemain_set.all()
    if images:
        return '<img src="%s">' % images[0].photo.url
    else:
        return ''
photo_for_product.allow_tags = True
Daniel Roseman
I wanted the output to be a string of the path to the image. Apparently, the issue is that images[0].photo is am ImageFieldFile and not a string.
BryanWheelock
I tried both your examples and both still return (None)
BryanWheelock
A: 

I wanted the output to be a string of the path to the image. Apparently, the issue is that images[0].photo is am ImageFieldFile and not a string.

It seems that by default, ImageFieldFile has the following attributes:
ImageFieldFile.name
ImageFieldFile.path
ImageFieldFile.url

All those attributes return unicode strings.

BryanWheelock