mmr
mmr

Reputation: 516

File does not upload and save in the database

I've been having problem in saving and uploading files in django. I've been reading the entire tutorial to get this up and running. I've been stuck with this:

'tuple' does not support the buffer interface

The problem seems to be coming from views.py, it stops somewhere between saving. I hope you could point me in the right direction..

My upload/views.py

# -*- 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 upload.models import Files
from upload.forms import DocumentForm

# import sys, traceback

def index(request):
    # Handle file upload
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = Files(file_path = request.FILES['file_path'])
            newdoc.save()
            # print(request)

        # Redirect to the document list after POST
        return HttpResponseRedirect(reverse('upload.views.index'))
    else:
        form = DocumentForm() # A empty, unbound form

    # Load documents for the list page
    documents = Files.objects.all()

    # print(form)
    print(documents)
    # Render list page with the documents and the form
    return render_to_response(
        'upload/index.html', {'documents': documents, 'form': form}, RequestContext(request)
)

my uploads/models.py

from django.db import models

# Create your models here.
class Files(models.Model):
    user_id = models.IntegerField()
    project_id = models.IntegerField()
    file_path = models.FileField(upload_to='documents/%Y/%m/%d')
    file_name = models.CharField(max_length=255)
    file_size = models.CharField(max_length=45)
    file_type = models.CharField(max_length=45)
    file_ext = models.CharField(max_length=10)
    file_width = models.SmallIntegerField()
    file_height = models.SmallIntegerField()
    file_tag = models.CharField(max_length=45)
    location = models.TextField()
    approved = models.IntegerField()
    archived = models.IntegerField()
    restored = models.IntegerField()
    backup = models.IntegerField()
    date_upload = models.DateTimeField()
    date_modified = models.DateTimeField()

    def __str__(self):
        return 'file_name:{0}'.format(self.file_name)

    class Meta:
        managed = False
        db_table = 'files'

upload/forms.py

# -*- coding: utf-8 -*-
from django import forms

class DocumentForm(forms.Form):
    file_path = forms.FileField(
        label='Select a file',
        help_text='max. 42 megabytes'
    )

Here is the full traceback:

    Environment:


Request Method: POST
Request URL: http://localhost:8000/upload/

Django Version: 1.9
Python Version: 3.4.3
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'gallery',
 'upload']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\core\handlers\base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\core\handlers\base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "G:\python\testify\upload\views.py" in index
  18.             newdoc.save()

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\base.py" in save
  697.                        force_update=force_update, update_fields=update_fields)

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\base.py" in save_base
  725.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\base.py" in _save_table
  809.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\base.py" in _do_insert
  848.                                using=using, raw=raw)

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\manager.py" in manager_method
  122.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\query.py" in _insert
  1037.         return query.get_compiler(using=using).execute_sql(return_id)

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\sql\compiler.py" in execute_sql
  985.             for sql, params in self.as_sql():

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\sql\compiler.py" in as_sql
  943.                 for obj in self.query.objs

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\sql\compiler.py" in <listcomp>
  943.                 for obj in self.query.objs

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\sql\compiler.py" in <listcomp>
  941.                     ) for f in fields

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\fields\files.py" in pre_save
  311.             file.save(file.name, file, save=False)

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\fields\files.py" in save
  90.         name = self.field.generate_filename(self.instance, name)

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\fields\files.py" in generate_filename
  332.         return os.path.join(self.get_directory_name(), self.get_filename(filename))

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\db\models\fields\files.py" in get_filename
  322.         return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename)))

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\utils\functional.py" in inner
  205.             self._setup()

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\core\files\storage.py" in _setup
  333.         self._wrapped = get_storage_class()()

File "c:\python\lib\site-packages\django-1.9.dev20150917232253-py3.4.egg\django\core\files\storage.py" in __init__
  185.         self.location = abspathu(self.base_location)

File "c:\python\lib\ntpath.py" in abspath
  547.                 path = _getfullpathname(path)

Exception Type: TypeError at /upload/
Exception Value: 'tuple' does not support the buffer interface

Upvotes: 0

Views: 193

Answers (2)

mmr
mmr

Reputation: 516

I think I've already solved my problem and I am posting this solution in case there are other newbies who's trying to make this work. Note: you better rename the name of the file field from 'file_path' to 'file' which is in my DocumentForm to avoid naming confusion

def index(request):
    # Handle file upload
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)

        if form.is_valid():
            # Upload the File
            uploaded_file(request)
            # Save in database
            newdoc = Files(
                file_path = 'media/'+request.FILES['file_path'].name,
                file_name = request.FILES['file_path'].name,
                file_size = request.FILES['file_path'].size,
                file_type = request.FILES['file_path'].content_type,
                # Other data fields here..
            )
            newdoc.save()

        # Redirect to the document list after POST
        return HttpResponseRedirect(reverse('upload.views.index'))
    else:
        form = DocumentForm() # A empty, unbound form

    # Load documents for the list page
    documents = Files.objects.all()

    # Render list page with the documents and the form
    return render_to_response(
        'upload/index.html', {'documents': documents, 'form': form}, RequestContext(request)
    )

def uploaded_file(request):
    uploaded_filename = request.FILES['file_path'].name

    # save the uploaded file inside that folder.
    full_filename = 'media/'+uploaded_filename
    fout = open(full_filename, 'wb+')

    file_content = ContentFile( request.FILES['file_path'].read() )

    # Iterate through the chunks.
    for chunk in file_content.chunks():
        fout.write(chunk)
    fout.close()

Upvotes: 0

Burhan Khalid
Burhan Khalid

Reputation: 174708

The FileField represents an uploaded file object. So you need to pass it a file and not a path.

def index(request):
    # Handle file upload
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = Files(file_path = form.cleaned_data['file_path'])
            newdoc.save()
            # print(request)

The documentation on file uploads goes into great detail on this.

Upvotes: 3

Related Questions