0

I am trying to set up a system in which user uploaded files will be given a path based on username and filename. The answer to this question seems to have pointed me in the right direction, but I'm having a little trouble with the implementation from the view.

I have a model that uses this:

class Document(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=100, blank=False, null=False)
    date = models.DateTimeField(auto_now=True)
    path = models.FileField(upload_to= custom_doc_file_path) # path should be /media/users/USERNAME/DOCUMENT_NAME

and custom_doc_file_path is defined like so:

def custom_doc_file_path(instance, filename):
    # creates media/users/USERNAME/FILENAME
    return '/'.join(['users', instance.user.username, get_directory_name(filename), filename]) 

def get_directory_name(filename):
    directory = filename.replace('.', '_')
    directory = directory.replace(' ', '_')
    return directory

This works great when uploading a file from the admin view, but I can't seem to replicate it from a view I'm creating. My view looks like this:

def create_button(request):
    if request.method == 'POST':
        document = Document.objects.create(
            user = request.user, 
            name = request.POST['name'], 
            path = request.POST['uploaded_file']            
        )
        document.save()

But when I try this the path is saved as the name of the file. If I try leaving the path blank and then saving the file to that path the model doesn't create a path at all. Additionally I would think that the file should be in request.FILES but this is shown as an empty dict.

Essentially I just want to know what I need to do to replicate the behavior of the admin when I add a new document through this model.

Community
  • 1
  • 1
Daniel Nill
  • 5,539
  • 10
  • 45
  • 63
  • Not using any forms? If you use `document = Document.objects.create(...)` you don't need `document.save()` https://docs.djangoproject.com/en/dev/topics/db/queries/#creating-objects – César Dec 23 '11 at 23:28

2 Answers2

1

Do you have enctype="multipart/form-data" set in your <form> tag? If request.FILES is empty, the problem isn't with your dynamic path generation (it hasn't gotten that far yet).

jeffknupp
  • 5,966
  • 3
  • 28
  • 29
  • well that was stupid. Anyways as a broader point, yes I should just use form models but I wanted to get it working before I obfuscated it any more. – Daniel Nill Dec 24 '11 at 02:44
0

First off, like @jknupp pointed out, don't forget to use enctype="multipart/form-data". Next you can try creating a form for your model:

forms.py

from models import Document
from django.forms import ModelForm

class DocumentForm(ModelForm):

    class Meta:
        model = Document

Update your view:

views.py

... #your imports
from forms import DocumentForm

...

def create_button(request): # create_button?
    ...
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid(): 
            form.save()
            return # redirect somewhere else
    ...
César
  • 9,939
  • 6
  • 53
  • 74