代码之家  ›  专栏  ›  技术社区  ›  darwhite

在Django的JSONField中放入ImageField

  •  0
  • darwhite  · 技术社区  · 3 年前

    我在django模型中有一个jsonfield,它应该在ImageField旁边保存一些其他字段。

    如何将图像的数据存储在该JSONField中,并将图像放在媒体目录中,当我想像常规图像字段一样在模板中使用它时,如何调用它。

    请注意,图像已经保存在媒体文件夹中,但我有要放在jsonfield中的文件名

    0 回复  |  直到 3 年前
        1
  •  0
  •   Godda    3 年前

    既然你还没有提供任何代码,我将尝试制作一些东西,然后你可以重构代码以满足你的需求!

    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)
    

    另一种选择是创建fields.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) 
    

    forms.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)