Search code examples
djangodjango-modelsdjango-formsdjango-uploads

Display image from ImageField by means of form


prelude:

Here's the simpliest way to display an ImageField. Lets assume I have 10 fields in my form and I don't wanna iterate over all of them in template.html just to check if it's an imageField and display it in a different way. I want to handle it via form or widget or something like this. So I want the leave template.html as it's bellow.

template.html

<table>
    {{ form.as_table }}
</table>

And add to models.py an image_tag method:

class UserProfile(Model):
  photo = ImageField(upload_to=PHOTO_DIRECTORY)
  contacts = TextField(null=True)
  ... others

  def image_tag(self):
    return u'<img src="%s" />' % self.photo.url

  image_tag.short_description = 'Image'
  image_tag.allow_tags = True

forms.py:

class UserProfileForm(forms.ModelForm):

  class Meta:
    model = UserProfile
    fields = ('contacts', 'photo', 'image_tag', ...others)

I get an error that Unknown field(s) (image_tag) specified for UserProfile which is fair enought.

I also tried to place it in readonly_fields but they don't display somehow. Do I have to create list_view? If yes where should it be?

What do I miss here? Why the image_tag method should be a part of model instead of form? Model describes how data should persists in the database, not how it should present to user via form. This should be a part of form, shouldn't it?. Correct me please if I'm wrong. How do I solve the issue? Any help would be greatly appreciated!


Solution

  • As Selcuk mentioned the simplest solution was to create my own widget.

    from string import Template
    from django.utils.safestring import mark_safe
    from django.forms import ImageField
    
    class PictureWidget(forms.widgets.Widget):
        def render(self, name, value, attrs=None, **kwargs):
            html =  Template("""<img src="$link"/>""")
            return mark_safe(html.substitute(link=value))
    
    class UserProfileForm(forms.ModelForm):
        photo = ImageField(widget=PictureWidget)