python - Django中带有ImageField的动态JsonForm
问题描述
我正在 Django 中创建一个动态表单(使用 JSON 格式),该表单需要使用 Django Storage 保存多个图像,并将对文件的引用保存在 JSON 字段中。
这就是我现在所拥有的,它可以工作但真的很难看,Django 已经这样做了,我不知道如何重用相同的功能。
Class SomeModel(models.ModelForm):
results = JSONField()
class DynamicJsonForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# ... Add dynamic fields to the form
self.extra = [] # Save the reference for the fields
class Meta:
model = SomeModel
exclude = ("results",)
def save(self, commit=True):
results = {}
for extra in self.extra:
value = self.cleaned_data.get(extra)
question = some_query.question
if "photo" in extra and value: # value = photo
filename, ext = value.name.split(".")
filename = "media/the/path/to/photos/{}_{}.{}".format(filename, uuid4().hex, ext)
uploaded_file = SimpleUploadedFile(filename, value.read(), value.content_type)
image = Image.open(uploaded_file)
if image.mode in ("RGBA", "P"):
image = image.convert("RGB")
image.save(fp=filename)
results[question][extra] = filename
else:
results[question][extra] = value
self.instance.results = results
return super().save(commit)
这实际上有效,它将数据保存到 JSONField(结果)并将图像保存到本地文件系统存储。
如何改进以使用 Django Storage 并使其变得简单?使用 DjangoModel.save()
似乎要容易得多,但我不能使用普通的ImageField()
,因为它需要是动态的
解决方案
我混合FileSystemStorage
了forms.ImageField
,根本不是一个完美的解决方案,但看起来更好。
字段.py
import os
from django import forms
from django.conf import settings
from django.core.files.storage import FileSystemStorage
class FormFileSystemStorageImageField(forms.ImageField, FileSystemStorage):
def __init__(self, location=None, *args, **kwargs):
super().__init__(*args, **kwargs) # Call ImageField __init__, I wonder how to call second parent's __init__
self._orig_location = location
self._location = os.path.join(settings.MEDIA_ROOT, location)
def storage_path(self, name):
return os.path.join(self._orig_location, name)
表格.py
from .fields import FormFileSystemStorageImageField
# ... Same as question code
def save(self, commit=True):
results = {}
for extra in self.extra:
value = self.cleaned_data.get(extra)
question = some_query.question
if "photo" in extra and value: # value = photo
image_field = self.fields.get(extra)
image_field.save(value.name, value)
results[question][extra] = image_field.storage_path(value.name)
else:
results[question][extra] = value
self.instance.results = results
return super().save(commit)
推荐阅读
- php - Amazon SNS 开发不发送短信
- powershell - Powershell 流水线:将 System.ServiceProcess.ServiceController 转换为 PSObject
- soap - 使用 OSI saber 时出生日期无效
- database - 在access中创建父子数据录入表单
- r - R - 如何获得 2 个阶跃函数的差值/总和?
- elasticsearch - Cloudwatch 到 Elasticsearch 在推送到 ES 之前解析/标记日志事件
- java - 使用 Java 解析器在 XML 属性中保留 /t 和 /n
- c - 在C中的字符串中返回置换
- sql - 多对多?
- javascript - 在html页面中编写javascript出现在页面中