0

I have a jsonfield inside of a django model which is supposed to hold some other fields alongside an ImageField.

How can I store the data of the image inside that JSONField and put the image inside the media directory and have it called when I want to use it inside of my template like a regular imagefield.

Please note that the image have already been saved inside the media folder but I have the name of the file which i want to put inside the jsonfield

darwhite
  • 31
  • 3

1 Answers1

0

Since you haven't provided any codes am going to try to make something and then you can refactor the code to suit your needs !

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)

An alternative is creating a fields.py and try this solution:

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) 

And forms.py to handle the fields , it's not the perfect solution, it's to give you an idea on how to go about it.

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)
Godda
  • 951
  • 1
  • 10
  • 26
  • I would try what it and get back to you. Sorry for the late response I had to move on to other parts of the project – darwhite Feb 06 '22 at 02:50