Django - Как загрузить изображения из шаблона?


Вот моя проблема. Вкратце, мое приложение преобразует одно или много изображений. И я хочу, чтобы пользователь мог загрузить преобразованные изображения, например, с помощью кнопки "Сохранить новые изображения". Когда пользователь нажимает на эту кнопку, появляется, например, окно Download, и он может загрузить все изображения, куда хочет, на свой компьютер. Не знаю, возможно ли это, жду ваших ответов.
Я уже выполнил часть загрузки изображений, она работает.

views.py

def mon_data(request, dataset_id):
    my_data = get_object_or_404(Dataset, pk=dataset_id)
    images_src = Image_Source.objects.filter(dataset = my_data)
    images_seg = []
    for src in images_src:
        images_seg.append(Image_Segmentee.objects.get(origine = src, model = src.model_initial))
    model = images_seg[0].model
    context = {
        "material": model.materiau_type, "model": model, 
        "images_seg": images_seg, "my_data": my_data, "nb_images":len(images_seg)
    }
    return render(request, "interface/my_data.html", context)

models.py

TYPES=[
    ('Metal', 'Metal'),
    ('Composite', 'Composite'),
]

DECISION=[
    ('En attente', 'En attente'),
    ('Valide', 'Valide'),
    ('Rejete', 'Rejete'),
]

class Modele(models.Model):
    name = models.CharField(max_length=100)
    materiau_type = models.CharField(max_length=20, choices=TYPES, null=False, blank=False)


class Dataset(models.Model):
    name = models.CharField(max_length=200, null=False, blank=False)
    date = models.DateField()

class Image_Source(models.Model):
    dataset = models.ForeignKey(Dataset, on_delete=models.CASCADE, null=True)
    materiau_type = models.CharField(max_length=20, choices=TYPES, null=False, blank=False)
    model_initial = models.ForeignKey(Modele, on_delete=models.SET_NULL, null=True)
    illustration = models.ImageField(null=False, blank=False, upload_to="img/")

class Image_Segmentee(models.Model):
    origine = models.ForeignKey(Image_Source, on_delete=models.CASCADE, null=True)        
    operator_decision = models.CharField(max_length=20, choices=DECISION, default='En attente')
    illustration = models.ImageField(null=False, blank=False, upload_to="img_modif/")
    model = models.ForeignKey(Modele, on_delete=models.SET_NULL, null=True)

interface/my_data.html

<div class="row">
     <div class="col s6">
                <p style="font-size: 200%; font-weight: bold;">Original image</p>
                {% for seg in images_seg %}
                    <a href="{% url 'mon_image' seg.origine.id %}">
                        <p style="color: black;">{{seg.origine}}</p>
                        <img class="img-data" src="{{ seg.origine.illustration.url }}" alt="image_src_echec">   
                    </a>
                {% endfor %}                             
      </div>
       <div class="col s6">
                <p style="font-size: 200%; font-weight: bold;">Segmented image</p>
                {% for seg in images_seg %}
                    <a href="{% url 'mon_image' seg.origine.id %}">
                        <p style="color: black;">{{seg}}</p>
                        <img class="img-data test1" src="{{ seg.illustration.url }}" alt="image_seg_echec">
                   </a>
                {% endfor %}                         
      </div>
</div>

Похоже, что вы хотите загрузить изображения в zip-файл, поэтому это может быть дубликатом: скачать изображения в zip-файл

С небольшими изменениями вы должны определить представление примерно так:

from zipfile import ZipFile
def download_image(request, id):
    # Modele seems to be the model holding the modified collection
    target_model=Modele.objects.get(pk=id)
    # get a qs of assigned illustrations
    segmentee_set = target_model.image_segmentee.all()
    
    with ZipFile('export.zip', 'w') as export_zip:
        for image_model in segmentee_set:
            img_path =  image_model.illustration.path
            # below line should result in .write("/media/somefolder/image123.png", image123.png)
            export_zip.write(img_path, img_path.split("/")[-1]) 

    wrapper = FileWrapper(open('export.zip', 'rb'))
    content_type = 'application/zip'
    content_disposition = 'attachment; filename=export.zip'

    response = HttpResponse(wrapper, content_type=content_type)
    response['Content-Disposition'] = content_disposition
    return response

Затем, конечно, добавьте представление к URL и попытайтесь получить доступ к этому URL непосредственно в браузере.

Обязательно прочтите об управлении файлами.

Если это решение было полезным, вам следует оптимизировать, проверить ошибки и исследовать, как генерируются и обслуживаются файлы в памяти, а также решить, хотите ли вы где-то хранить сгенерированные zip-файлы или вам придется генерировать их каждый раз.

Вернуться на верх