Django Basic File Upload

As part of the ongoing improvements to the web site http://www.rc-stats.com/, I have decided that I want contributors to be able to upload race results. Currently I am using a python script to upload the results myself.

Some Back Ground on The Current Process

Currently I use set of python scripts and pgdb to parse the race results and feed them into the postgresql database. The code to feed results into the database was a bit rough and certainly not robust enough enough for contributors to work with (it has been a bit of bootstrapping as I learned more about security with respect to django and postgresql).

This was a design decision I made early on. That I would prioritize getting results into the system quickly, the consequence being that I would need to manually run script to upload races results every time they became available. Now that the site is live and I am able to start getting user feedback, the time has come for me to clean up this process.

References To Start From

Initial Prototype

Using the django documentation and some stackoverflow examples I arrived at the following code.

upload_start.html

{% extends "base.html" %}

{% block pagetitle %}Upload Race Results{% endblock %}
{% block pagetitle_description %}Upload race results from the scoring system.{% endblock %}

{% block content %}

<section class="full_width">
<h2>{{ error_status }}</h2>
	<form action="/upload_start/" method="post" enctype="multipart/form-data">
	{% csrf_token %}
	<input type="file" name="file" />
	<input type="submit" name="submit" value="Upload" />
</form>

{{ form.errors }}
{{ form.non_field_errors }}
</section><!-- /.full_width -->
{% endblock %}

views.py

class UploadFileForm(forms.Form):
    #title = forms.CharField(max_length=50)
    file  = forms.FileField()

@login_required(login_url='/login')
def upload_start(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)

        # What causes the form to not be valid?
        if form.is_valid():
            # Need to make sure the key used for FILES[ ] matches up with the
            # form in the template.
            handle_uploaded_file(request.FILES['file'])
            return HttpResponseRedirect('/upload_start')
        else:
            error = "Failed to upload file:" + request.FILES['file'].name
            return render_to_response('upload_start.html', {'form':form, 'error_status': error}, context_instance=RequestContext(request))

    else:
        form = UploadFileForm()
    return render_to_response('upload_start.html', {'form': form}, context_instance=RequestContext(request))

def handle_uploaded_file(f):
    #print "name:", f.name
    #print "size:", f.size
    with open('/home/username/Desktop/rcstats/rcdata_media/fileupload/testfile.txt', 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

Some of the initial stumbling points I hit that are worth a note:

Result

At this stage, this is sufficient to result in a file getting placed in the assigned directory. I am in the process of designing the E2E user experience through this process, I will follow up with an additional post to cover the next steps.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s