Django's transition from oldforms to newforms is nearing. If you're using recent trunk source code from Django's subversion repository, you should start using newforms.
But there are still some rough edges as of today. File uploading seems to be one of them. (Adrian and other Django folks are well aware of this. Please don't bother them by asking "Are we there yet?")
The Django mailing lists and Google searching didn't turn up any best practices for this area of newforms, so I muddled through it and here's the result. I omit the urls.py code necessary to hook up the zip_upload method to a URL, but otherwise this should be complete.
And if I haven't loaded this with enough caveats...please be aware this code may be obsoleted soon.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | #!/usr/bin/env python
"""Please be aware this code is a stopgap measure that should go away when
more complete support for file uploading is added to newforms.
This demonstrates one way to do HTTP file upload using Django's groovy
new "newforms" approach. There isn't a FileField-type class for newforms
yet (as of March 9th, 2007), so you must do some additional work to fetch
the uploaded content."""
try:
import cStringIO as StringIO
except ImportError:
import StringIO
import zipfile
from django import http
from django import newforms as forms
from django.shortcuts import render_to_response
from django.contrib.auth.decorators import login_required
# You will probably want to work with one or more of your model classes.
#from mysite.pix.models import Picture
class ZipUploadForm(forms.Form):
"""A django.newforms class that uses a FileInput widget to accept
uploaded .ZIP files."""
zip_file = forms.Field(widget=forms.FileInput())
owner = forms.CharField(max_length=80)
def clean_zipfile(self):
if 'zip_file' in self.clean_data:
zip_file = self.clean_data['zip_file']
if zip_file.get('content-type') != 'application/zip':
msg = 'Only .ZIP archive files are allowed.'
raise forms.ValidationError(msg)
else:
# Verify that it's a valid zipfile
zip = zipfile.ZipFile(StringIO(zip_file['content']))
bad_file = zip.testzip()
zip.close()
del zip
if bad_file:
msg = '"%s" in the .ZIP archive is corrupt.' % (bad_file,)
raise forms.ValidationError(msg)
return zip_file
def save(self):
owner = self.clean_data['owner']
zipdata = self.clean_data['zip_file']['content']
zip = zipfile.ZipFile(StringIO.StringIO(zipdata))
for filename in zip.namelist():
# Do something here with each file in the .ZIP archive.
#
# For example, if you expect the archive to contain image
# files, you could process each one with PIL, then create
# and populate your models.Picture object and save it.
#data = zip.read(filename)
#pic = Picture(owner, filename, data)
#pic.save()
pass
zip.close()
@login_required
def zip_upload(request, template='zipupload.html'):
form = None
# Typically, we'd do a permissions check here.
#if not request.user.has_perm('pix.add_picture'):
# return http.HttpResponseForbidden('You cannot add pictures.')
if request.POST:
post_data = request.POST.copy()
post_data.update(request.FILES)
form = ZipUploadForm(post_data)
if form.is_valid():
success = form.save()
return http.HttpResponseRedirect('/pix/upload_success/')
else:
form = ZipUploadForm()
return render_to_response(template, {'form':form})
# Example template for "zipupload.html"
{% extends "base.html" %}
{% block content %}
<div class="content">
<h1>Upload a .Zip file</h1>
<div class="body">
<p>
<form action="/zip_upload/" method="post"
enctype="multipart/form-data">
<table>
{{ form }}
</table>
<input type="submit" value="Upload ZIP" />
</form>
</p><br />
<p>Some helpful text really should go here.</p>
</div>
</div>
{% endblock %}
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
This snippet is out of date - newforms now supports file uploads on its own, and does not require you to write your own support as in this snippet.
#
Please login first before commenting.