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!
As Selcuk mentioned the simplest solution was to create my own widget.
Let me improve this interesting question. I suggest to combine image input and image preview. Subclass FileInput widget and override render to concatenate additional html to display preview image and default input image html.
I can't comment yet, thus I need to add this via an Answer. All credits to deathangel908 for this handy solution.
I'm using Django 2.1 and was struck with
TypeError: render() got an unexpected keyword argument 'renderer'
error when trying the accepted answer. Solution to this problem can be found here: https://stackoverflow.com/a/52039655/8002464In short, the solution must be slightly changed for Django 2.1 and upwards and include
renderer=None
. Fully updated solution:Btw. a quick small improvement, at least for my use-case was to add the media url. This way the images were actually shown instead of being lost in wrong urls. But this might only be because of how I set up my urls.