简体   繁体   中英

Unzip user uploaded files through models in Django

The user can upload zip file through models.py but I can not then unzip the file to iterate through the images and display them in my template.

Models.py

from django.db import models
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.conf import settings
from .validators import validate_file_extension

class Post(models.Model):
  title = models.CharField(max_length=140) 
  body = models.TextField(max_length=250)
  date = models.DateTimeField(auto_now=True, auto_now_add=False)
  album_image = models.FileField(validators=[validate_file_extension])
  user = models.ForeignKey(User, default=1) 

  def get_absolute_url(self):
     return reverse('photos:detail',kwargs={'pk':self.pk})

  def __str__(self):
     return self.title

views.py

Post create and index view works/ or at least worked until i changed from uploading a single image to uploading zip files and trying to iterate

class IndexView(generic.ListView):
    template_name='photos/post.html'
    def get_queryset(self):
        return Post.objects.filter(user=self.request.user)

def DetailView(request,pk=""):
    model = Post
    z = zipfile.ZipFile()   ### I am unsure of what goes here!!
    context = {
        "images": z,
        }
    template_name = 'photos/detail.html'
    return render(request,template_name,context)

class PostCreate(generic.CreateView):
    form = PostForm()
    model = Post
    fields = ['title','body','album_image']
    if form.is_valid():
        instance = form.save(commit=False)
        username = form.cleaned_data['username']
        album_image = form.cleaned_data['album_image']
        instance.save()
        context = {
        "form": form,
        }

detail.html

{% extends "homepage/header.html" %}
{% block content %}

{% for image in image%}

<img src ="{{image.url}}" style="width:304px;height:228px;">

{% endif%}
<h1>{{post.title}}</h1>
<h3>{{post.user}}</h3>
<h3>{{post.body}}</h3>
<h3>{{post.date}}</h3>
{% endblock %}

post_form.html

<html>
<body>
{% if request.user.is_authenticated%}
<h3>Hello {{request.user.username}}, please upload your folder as a .zip file</h3>
{% endif %}
<div class="container-fluid">

    <div class="row">

        <div class="col-sm-12 col-md-7">
            <div class="panel panel-default">
                <div class="panel-body">
                   {% if request.user.is_authenticated %}
             <form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
                        {% csrf_token %}
                {{form.as_p}}
                            <div class="col-sm-offset-2 col-sm-10">
                                <button type="submit" class="btn btn-success">Submit</button>
                            </div>
                        </div>
                    </form>
        {% else %}
        <p>You must be logged in to upload a file</p>
                {% endif %}
        </div>
            </div>
        </div>
</body>

</html>

post.html

{% extends "homepage/header.html" %}
{% block content %}

{%if object_list %}
<ul>
    {% for album in object_list %}
    <h3><a href = "{% url 'photos:detail' album.id %}">{{album.title}} - {{album.date}}</a></h3><br>
    {% endfor %}
</ul>

{% else %}
    <h3>You have no photo albums!</h3>
{% endif %}

{% endblock %}

I'd be careful with the zip contents and probably check on the filename/types in the loop here, but something like the following might work (untested). Basically extracts the contents assuming not in subfolders in the zip, then base64encodes them and uses that encoded version in the src specifying the data type.

# views.py  
import base64
import zipfile

def DetailView(request,pk=""):
    model = Post
    # z = zipfile.ZipFile()   ### I am unsure of what goes here!!
    mydoc = 'path_to_zip_file_here'
    # probably should do some logic on the name and file type
    # or be very aware of what is in the zip file
    with zipfile.ZipFile(mydoc, 'r') as z:
        for f in z.namelist():
            images.update({f: base64.b64encode(z.read(f)),})

    context = {
        "images": images,
        }
    template_name = 'photos/detail.html'
    return render(request,template_name,context)

and in detail.html:

{% for name, image in images.items %}
<img src ="data:image/jpeg;base64,{{ image }}" style="width:304px;height:228px;">
{% endfor%} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM