Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload a file in Django? [closed]

As a newbie to Django, I am having difficulty making an upload app in Django 1.3. I could not find any up-to-date example/snippets. May someone post a minimal but complete (Model, View, Template) example code to do so?

like image 678
qliq Avatar asked May 03 '11 15:05

qliq


People also ask

How do I upload a text file in Django?

Django provides built-in library and methods that help to upload a file to the server. The forms. FileField() method is used to create a file input and submit the file to the server. While working with files, make sure the HTML form tag contains enctype="multipart/form-data" property.

What is chunk in Django?

chunk_size. Size, in bytes, of the “chunks” Django should store into memory and feed into the handler. That is, this attribute controls the size of chunks fed into FileUploadHandler.


1 Answers

Phew, Django documentation really does not have good example about this. I spent over 2 hours to dig up all the pieces to understand how this works. With that knowledge I implemented a project that makes possible to upload files and show them as list. To download source for the project, visit https://github.com/axelpale/minimal-django-file-upload-example or clone it:

> git clone https://github.com/axelpale/minimal-django-file-upload-example.git 

Update 2013-01-30: The source at GitHub has also implementation for Django 1.4 in addition to 1.3. Even though there is few changes the following tutorial is also useful for 1.4.

Update 2013-05-10: Implementation for Django 1.5 at GitHub. Minor changes in redirection in urls.py and usage of url template tag in list.html. Thanks to hubert3 for the effort.

Update 2013-12-07: Django 1.6 supported at GitHub. One import changed in myapp/urls.py. Thanks goes to Arthedian.

Update 2015-03-17: Django 1.7 supported at GitHub, thanks to aronysidoro.

Update 2015-09-04: Django 1.8 supported at GitHub, thanks to nerogit.

Update 2016-07-03: Django 1.9 supported at GitHub, thanks to daavve and nerogit

Project tree

A basic Django 1.3 project with single app and media/ directory for uploads.

minimal-django-file-upload-example/     src/         myproject/             database/                 sqlite.db             media/             myapp/                 templates/                     myapp/                         list.html                 forms.py                 models.py                 urls.py                 views.py             __init__.py             manage.py             settings.py             urls.py 

1. Settings: myproject/settings.py

To upload and serve files, you need to specify where Django stores uploaded files and from what URL Django serves them. MEDIA_ROOT and MEDIA_URL are in settings.py by default but they are empty. See the first lines in Django Managing Files for details. Remember also set the database and add myapp to INSTALLED_APPS

... import os  BASE_DIR = os.path.dirname(os.path.dirname(__file__)) ... DATABASES = {     'default': {         'ENGINE': 'django.db.backends.sqlite3',         'NAME': os.path.join(BASE_DIR, 'database.sqlite3'),         'USER': '',         'PASSWORD': '',         'HOST': '',         'PORT': '',     } } ... MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/' ... INSTALLED_APPS = (     ...     'myapp', ) 

2. Model: myproject/myapp/models.py

Next you need a model with a FileField. This particular field stores files e.g. to media/documents/2011/12/24/ based on current date and MEDIA_ROOT. See FileField reference.

# -*- coding: utf-8 -*- from django.db import models  class Document(models.Model):     docfile = models.FileField(upload_to='documents/%Y/%m/%d') 

3. Form: myproject/myapp/forms.py

To handle upload nicely, you need a form. This form has only one field but that is enough. See Form FileField reference for details.

# -*- coding: utf-8 -*- from django import forms  class DocumentForm(forms.Form):     docfile = forms.FileField(         label='Select a file',         help_text='max. 42 megabytes'     ) 

4. View: myproject/myapp/views.py

A view where all the magic happens. Pay attention how request.FILES are handled. For me, it was really hard to spot the fact that request.FILES['docfile'] can be saved to models.FileField just like that. The model's save() handles the storing of the file to the filesystem automatically.

# -*- coding: utf-8 -*- from django.shortcuts import render_to_response from django.template import RequestContext from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse  from myproject.myapp.models import Document from myproject.myapp.forms import DocumentForm  def list(request):     # Handle file upload     if request.method == 'POST':         form = DocumentForm(request.POST, request.FILES)         if form.is_valid():             newdoc = Document(docfile = request.FILES['docfile'])             newdoc.save()              # Redirect to the document list after POST             return HttpResponseRedirect(reverse('myapp.views.list'))     else:         form = DocumentForm() # A empty, unbound form      # Load documents for the list page     documents = Document.objects.all()      # Render list page with the documents and the form     return render_to_response(         'myapp/list.html',         {'documents': documents, 'form': form},         context_instance=RequestContext(request)     ) 

5. Project URLs: myproject/urls.py

Django does not serve MEDIA_ROOT by default. That would be dangerous in production environment. But in development stage, we could cut short. Pay attention to the last line. That line enables Django to serve files from MEDIA_URL. This works only in developement stage.

See django.conf.urls.static.static reference for details. See also this discussion about serving media files.

# -*- coding: utf-8 -*- from django.conf.urls import patterns, include, url from django.conf import settings from django.conf.urls.static import static  urlpatterns = patterns('',     (r'^', include('myapp.urls')), ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 

6. App URLs: myproject/myapp/urls.py

To make the view accessible, you must specify urls for it. Nothing special here.

# -*- coding: utf-8 -*- from django.conf.urls import patterns, url  urlpatterns = patterns('myapp.views',     url(r'^list/$', 'list', name='list'), ) 

7. Template: myproject/myapp/templates/myapp/list.html

The last part: template for the list and the upload form below it. The form must have enctype-attribute set to "multipart/form-data" and method set to "post" to make upload to Django possible. See File Uploads documentation for details.

The FileField has many attributes that can be used in templates. E.g. {{ document.docfile.url }} and {{ document.docfile.name }} as in the template. See more about these in Using files in models article and The File object documentation.

<!DOCTYPE html> <html>     <head>         <meta charset="utf-8">         <title>Minimal Django File Upload Example</title>        </head>     <body>     <!-- List of uploaded documents -->     {% if documents %}         <ul>         {% for document in documents %}             <li><a href="{{ document.docfile.url }}">{{ document.docfile.name }}</a></li>         {% endfor %}         </ul>     {% else %}         <p>No documents.</p>     {% endif %}          <!-- Upload form. Note enctype attribute! -->         <form action="{% url 'list' %}" method="post" enctype="multipart/form-data">             {% csrf_token %}             <p>{{ form.non_field_errors }}</p>             <p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>             <p>                 {{ form.docfile.errors }}                 {{ form.docfile }}             </p>             <p><input type="submit" value="Upload" /></p>         </form>     </body> </html>  

8. Initialize

Just run syncdb and runserver.

> cd myproject > python manage.py syncdb > python manage.py runserver 

Results

Finally, everything is ready. On default Django developement environment the list of uploaded documents can be seen at localhost:8000/list/. Today the files are uploaded to /path/to/myproject/media/documents/2011/12/17/ and can be opened from the list.

I hope this answer will help someone as much as it would have helped me.

like image 128
Akseli Palén Avatar answered Sep 19 '22 13:09

Akseli Palén