2

I would like my file upload to be renamed before being saved to disk. The logic I want to use to set the name would be contained in the view.

I want to pass my getname variable from my view into my model class before saving. Here is my broken code.

View:

getname = 'foo' #I want this string to get passed into upload_to in the model

form = DocumentForm(request.POST, request.FILES)

if form.is_valid(): 

    newdoc = Document()
    newdoc.filename = getname #This line doesn't work
    newdoc.docfile = request.FILES['docfile']
    newdoc.save()

Model:

class Document(models.Model):

    filename = ''
    docfile = models.FileField(upload_to=filename)

I have read through several of these links but whenever I touch my code I break it.

http://www.malloc.co/django/django-rename-a-file-uploaded-by-a-user-before-saving/ http://catherinetenajeros.blogspot.com/2013/03/rename-path-when-imagefile-upload.html

Edit: I've revised the code to help make my question more clear.

abaldwin99
  • 903
  • 1
  • 8
  • 26
  • 1
    Where will `getname` come from? Is it an attribute in the model instance? Could it be? Will be easier if it is but I may have a solution even if not. – Alex Apr 22 '14 at 01:30
  • I have revised the original question. Does that make sense? – abaldwin99 Apr 23 '14 at 00:12
  • 1
    I understand what you want, but I'm wondering where the `getname` will come from each time. Where are you getting `'foo'`? Also, is `filename` in your model some type of Field? I.e. should it be `filename = models.CharField(max_length=10)`? – Alex Apr 23 '14 at 00:18
  • @Alex getname comes from what my user types into a textbox on my HTML form. `getname = request.POST.get('NameBox')` I'm trying to digest your response below...Thanks for the help thus far. – abaldwin99 Apr 23 '14 at 01:08
  • OK. Let me know if you have any troubles. If you're not already, I would recommend using a ModelForm` for `DocumentForm`, as it will automate much of the stuff I noted in the example. ModelForm docs [here](https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#modelform). – Alex Apr 23 '14 at 01:15

2 Answers2

3

I think this is what you want, assuming getname is entered into the form in your view:

First, your model:

def upload_function(instance, filename):
    getname = instance.name
    # Add other filename logic here
    return customfilename # Return the end filename where you want it saved.

class Document(models.Model):

    name = models.CharField(max_length=25)
    docfile = models.FileField(upload_to=upload_function) # The upload_to argument sends it to your upload function.

In this case, you're creating your own upload_to function (here called upload_function). You can read about that here. When running this function, it will pass the instance as a first argument, so you can access its properties. Thus, we'll access its name when creating our filename. Further explanation here.

Now your view:

from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import DocumentForm
from .models import Document

def upload_file(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            instance = Document(docfile=request.FILES['file'])
            instance.save()
            return HttpResponseRedirect('/success/url/')
    else:
        form = DocumentForm()
    return render(request, 'upload.html', {'form': form})

This view checks your form to make sure it's valid, then saves the uploaded file. Assuming your DocumentForm has a field for name, this will be assigned first, which means your function for upload_to will be able to access it. The sample language for this view came from the Django docs here.

Please let me know if this works.

Community
  • 1
  • 1
Alex
  • 8,321
  • 1
  • 34
  • 30
1

If i understand correctly , you're looking for something like this ,

newdoc.instance.your_attribute = getname
Ramez Ashraf
  • 873
  • 6
  • 14