dea*_*908 3 django django-models django-forms django-uploads
前奏:
这是显示ImageField的最简单方法.让我们假设我的表单中有10个字段,我不想迭代它们template.html只是为了检查它是否是一个imageField并以不同的方式显示它.我想通过形式或插件之类的东西来处理它这个.所以我想要离开template.html,因为它在下面.
template.html
<table>
{{ form.as_table }}
</table>
Run Code Online (Sandbox Code Playgroud)
并向models.py添加一个image_tag方法:
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
Run Code Online (Sandbox Code Playgroud)
forms.py:
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('contacts', 'photo', 'image_tag', ...others)
Run Code Online (Sandbox Code Playgroud)
我得到了一个Unknown field(s) (image_tag) specified for UserProfile公平的错误.
我也尝试将它放入,readonly_fields但它们不会以某种方式显示.我是否必须创建list_view?如果是的话应该在哪里?
我在这里想念什么?为什么该image_tag方法应该是模型的一部分而不是形式?模型描述了数据应该如何在数据库中持久化,而不是如何通过表单呈现给用户.这应该是形式的一部分,不应该吗?如果我错了,请纠正我.我该如何解决这个问题?任何帮助将不胜感激!
作为塞尔丘克提到的最简单的解决方案是创建自己的控件.
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)
Run Code Online (Sandbox Code Playgroud)
让我改进这个有趣的问题。我建议将图像输入和图像预览结合起来。子类 FileInput 小部件并覆盖渲染以连接其他 html 以显示预览图像和默认输入图像 html。
from django.utils.safestring import mark_safe
from django import forms
class ImagePreviewWidget(forms.widgets.FileInput):
def render(self, name, value, attrs=None, **kwargs):
input_html = super().render(name, value, attrs=None, **kwargs)
img_html = mark_safe(f'<br><br><img src="{value.url}"/>')
return f'{input_html}{img_html}'
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = '__all__'
photo = forms.ImageField(widget=ImagePreviewWidget,)
Run Code Online (Sandbox Code Playgroud)
我还不能发表评论,因此我需要通过答案添加此内容。所有这些都归功于 Deathangel908 提供的这个方便的解决方案。
TypeError: render() got an unexpected keyword argument 'renderer'我正在使用 Django 2.1,在尝试接受的答案时遇到了错误。此问题的解决方案可以在这里找到:https ://stackoverflow.com/a/52039655/8002464
简而言之,对于 Django 2.1 及更高版本,解决方案必须稍作更改并包含renderer=None. 完全更新的解决方案:
from string import Template
from django.utils.safestring import mark_safe
from django.forms ImageField
class PictureWidget(forms.widgets.Widget):
def render(self, name, value, attrs=None, renderer=None):
html = Template("""<img src="$link"/>""")
return mark_safe(html.substitute(link=value))
class UserProfileForm(forms.ModelForm):
photo = ImageField(widget=PictureWidget)
Run Code Online (Sandbox Code Playgroud)
顺便提一句。至少对于我的用例来说,一个快速的小改进是添加媒体网址。这样,图像就会实际显示出来,而不是丢失在错误的 URL 中。但这可能只是因为我设置网址的方式不同。
from django.conf import settings
[...]
html = Template("""<img src="$media$link"/>""")
return mark_safe(html.substitute(media=settings.MEDIA_URL, link=value))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5709 次 |
| 最近记录: |